Implemented Contour Finding

Before contours can be found, video is converted to grayscale,
background subtraction is performed and results get binarized.

Circles are characterized by the aspect ratio of the individual blob.
This commit is contained in:
Mario Fleischmann 2021-05-06 09:48:06 +02:00
parent 4ab1557f30
commit 3ffa0ac381
3 changed files with 89 additions and 1 deletions

View File

@ -0,0 +1,3 @@
Video mit FFMPEG verkleinern:
ffmpeg -i beer.mkv -s 568x320 -c:a copy shrink.mkv

View File

@ -1,23 +1,94 @@
#include "ofApp.h" #include "ofApp.h"
#define VIDEO_WIDTH 568
#define VIDEO_HEIGHT 320
//-------------------------------------------------------------- //--------------------------------------------------------------
void ofApp::setup(){ void ofApp::setup(){
vidPlayer.load("beer.mkv"); // in /bin/data/
vidPlayer.play();
vidPlayer.setLoopState(OF_LOOP_NORMAL);
colorVideo.allocate(VIDEO_WIDTH, VIDEO_HEIGHT);
grayVideo.allocate(VIDEO_WIDTH, VIDEO_HEIGHT);
learnBackground = true;
threshhold = 80;
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
void ofApp::update(){ void ofApp::update(){
vidPlayer.update();
colorVideo.setFromPixels(vidPlayer.getPixels());
grayVideo = colorVideo; // Convert Color to Grayscale
if (learnBackground){
background = grayVideo;
learnBackground = false;
}
// Background subtraction
binarized.absDiff(background, grayVideo);
// Binarization
binarized.threshold(threshhold);
contourFinder.findContours(
binarized,
10,
VIDEO_HEIGHT * VIDEO_WIDTH / 10,
10,
true);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
void ofApp::draw(){ void ofApp::draw(){
ofSetHexColor(0xffffff);
colorVideo.draw(20, 20);
grayVideo.draw(40 + VIDEO_WIDTH, 20);
background.draw(20, 40 + VIDEO_HEIGHT);
binarized.draw(40 + VIDEO_WIDTH, 40 + VIDEO_HEIGHT);
ofFill();
ofSetHexColor(0x333333);
ofDrawRectangle(40 + VIDEO_WIDTH, 60 + VIDEO_HEIGHT + VIDEO_HEIGHT, VIDEO_WIDTH, VIDEO_HEIGHT);
ofSetHexColor(0xffffff);
for (int i = 0; i < contourFinder.blobs.size(); i++) {
ofxCvBlob blob = contourFinder.blobs[i];
// draw over the centroid if the blob is a hole
ofSetColor(255);
// https://docs.opencv.org/master/d1/d32/tutorial_py_contour_properties.html
float aspect_ratio = blob.boundingRect.getWidth() / blob.boundingRect.getHeight();
stringstream sizeStr;
sizeStr << std::to_string(i) << ": " << std::to_string(contourFinder.blobs[i].area);
sizeStr << " | F=" << aspect_ratio;
if (aspect_ratio > 0.5 && aspect_ratio < 1.5)
{
blob.draw(40 + VIDEO_WIDTH, 60 + VIDEO_HEIGHT + VIDEO_HEIGHT);
ofDrawBitmapString(sizeStr.str(),
contourFinder.blobs[i].boundingRect.getCenter().x + 40 + VIDEO_WIDTH,
contourFinder.blobs[i].boundingRect.getCenter().y + 60 + VIDEO_HEIGHT + VIDEO_HEIGHT);
}
}
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
void ofApp::keyPressed(int key){ void ofApp::keyPressed(int key){
if (key == '-') threshhold--;
else if (key == '+') threshhold++;
else if (key == ' ') learnBackground = true;
else if (key == '0') vidPlayer.setPaused(!vidPlayer.isPaused());
else if (key == OF_KEY_RIGHT) vidPlayer.nextFrame();
else if (key == OF_KEY_LEFT) vidPlayer.previousFrame();
else;
} }
//-------------------------------------------------------------- //--------------------------------------------------------------

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "ofMain.h" #include "ofMain.h"
#include "ofxOpenCv.h"
class ofApp : public ofBaseApp{ class ofApp : public ofBaseApp{
@ -21,4 +22,17 @@ class ofApp : public ofBaseApp{
void dragEvent(ofDragInfo dragInfo); void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg); void gotMessage(ofMessage msg);
ofVideoPlayer vidPlayer;
// Images displaying original video
ofxCvColorImage colorVideo;
ofxCvGrayscaleImage grayVideo;
ofxCvGrayscaleImage background;
ofxCvGrayscaleImage binarized;
ofxCvContourFinder contourFinder;
bool learnBackground;
int threshhold;
}; };