Browse Source

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.
fleischmannma75068
Mario Fleischmann 1 year ago
parent
commit
3ffa0ac381
3 changed files with 90 additions and 2 deletions
  1. 3
    0
      beerpong/bin/data/README.txt
  2. 73
    2
      beerpong/src/ofApp.cpp
  3. 14
    0
      beerpong/src/ofApp.h

+ 3
- 0
beerpong/bin/data/README.txt View File

@@ -0,0 +1,3 @@
Video mit FFMPEG verkleinern:

ffmpeg -i beer.mkv -s 568x320 -c:a copy shrink.mkv

+ 73
- 2
beerpong/src/ofApp.cpp View File

@@ -1,23 +1,94 @@
#include "ofApp.h"

#define VIDEO_WIDTH 568
#define VIDEO_HEIGHT 320

//--------------------------------------------------------------
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(){

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(){

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){

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;
}

//--------------------------------------------------------------

+ 14
- 0
beerpong/src/ofApp.h View File

@@ -1,6 +1,7 @@
#pragma once

#include "ofMain.h"
#include "ofxOpenCv.h"

class ofApp : public ofBaseApp{

@@ -21,4 +22,17 @@ class ofApp : public ofBaseApp{
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
ofVideoPlayer vidPlayer;

// Images displaying original video
ofxCvColorImage colorVideo;
ofxCvGrayscaleImage grayVideo;

ofxCvGrayscaleImage background;
ofxCvGrayscaleImage binarized;

ofxCvContourFinder contourFinder;

bool learnBackground;
int threshhold;
};

Loading…
Cancel
Save