open frame worksでopenCVをやっちゃいます.
open frame works(以下oF)はプログラミング自体がとても簡略化されているのでプロトタイプの作成向きです.動作は重いとのことですが,リリースするものでなければそれほど難しくありません.
なおかつiPhone,Androidようにテンプレートがあり,そこに書き込めばスマホアプリが作れてしまいます.(AndroidやopenCVは未確認)
これはXCODEでのテストです
#pragma once
#include "ofMain.h"
#include "ofxOpenCv.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
ofVideoGrabber movie;
ofxCvColorImage rgb,hsb;
ofxCvGrayscaleImage hue,sat,bri,filtered;
ofxCvContourFinder contours;
int w,h;
int findHue;
};
そしてこっちも必要
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofBackground(0,0,0);
w = 320;
h = 240;
movie.initGrabber(w, h, true);
//reserve memory for cv images
rgb.allocate(w, h);
hsb.allocate(w, h);
hue.allocate(w, h);
sat.allocate(w, h);
bri.allocate(w, h);
filtered.allocate(w, h);
}
//--------------------------------------------------------------
void ofApp::update(){
movie.update();
if (movie.isFrameNew()) {
//copy webcam pixels to rgb image
rgb.setFromPixels(movie.getPixels(), w, h);
//mirror horizontal
rgb.mirror(false, true);
//duplicate rgb
hsb = rgb;
//convert to hsb
hsb.convertRgbToHsv();
//store the three channels as grayscale images
hsb.convertToGrayscalePlanarImages(hue, sat, bri);
//filter image based on the hue value were looking for
for (int i=0; i<w*h; i++) {
filtered.getPixels()[i] = ofInRange(hue.getPixels()[i],findHue-5,findHue+5) ? 255 : 0;
}
filtered.flagImageChanged();
//run the contour finder on the filtered image to find blobs with a certain hue
contours.findContours(filtered, 20, w*h/2, 2, false);//last numeric 2 is find maximum cout
}
}
//--------------------------------------------------------------
void ofApp::draw(){
ofSetColor(255,255,255);
//draw all cv images
rgb.draw(0,0);
hsb.draw(640,0);
hue.draw(0,240);
sat.draw(320,240);
bri.draw(640,240);
filtered.draw(0,480);
contours.draw(0,480);
ofSetColor(255, 0, 0);
ofFill();
//draw red circles for found blobs
for (int i=0; i<contours.nBlobs; i++) {
ofCircle(contours.blobs[i].centroid.x, contours.blobs[i].centroid.y, 10);// last text 10 is radius od draw circle
}
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
//calculate local mouse x,y in image
int mx = x % w;
int my = y % h;
//get hue value on mouse position
findHue = hue.getPixels()[my*w+mx];
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
}
混乱を防ぐために,テンプレデフォルトのまま書き足しています
実行結果はこんな様子

実行して,抽出したい色をクリックするとそこに赤丸が表示されます
抽出数はofApp.cppの49行目
contours.findContours(filtered, 20, w*h/2, 2, false);
のfalseの前の2で変えられます.2なら2個検出.