0

フレーム間の動き (absdiff、threshold、erode など) を検出するために、フレーム差分と opencv を使用しています。

基本的に白いブロブの動きの個々の位置の座標(四角形:x、y、幅、高さ)を取得するにはどうすればよいですか?

4

2 に答える 2

2

私も同じことをしています。これが私が持っているコードです(いくつかは異なるクラスで処理されますが、ここにすべてまとめました)。最初の部分はすでに持っているものです。輪郭の部分までスキップしてください。

/* This is the background subtraction you already have */
Mat tmp1;
GaussianBlur( frame, tmp1, Size(5,5),0,0); //Blurring one image is sufficient to eliminate noise
absdiff(tmp1, frameLast, tmp1);
cvtColor(tmp1,tmp1,CV_RGB2GRAY);
threshold( tmp1, tmp1, CV_THRESH_OTSU, 100, CV_THRESH_BINARY);
/*cleaning up */
int erosion_type = MORPH_RECT; // MORPH_RECT, MORPH_CROSS, MORPH_ELLIPSE
int erosion_size = 3;
Mat erosion_element = getStructuringElement( erosion_type, Size( 2*erosion_size + 1, 2*erosion_size+1), Point( erosion_size, erosion_size));

int dilation_type = MORPH_RECT;
int dilation_size = 5;
Mat dilation_element = getStructuringElement( dilation_type, Size( 2*dilation_size + 1, 2*dilation_size+1), Point( dilation_size, dilation_size));

erode(tmp1,tmp1,erosion_element);
dilate(tmp1,tmp1,dilation_element);

/* Here I am getting the contours */
vector<vector<Point> > contours;
findContours( tmp1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
int minArea = 100, maxArea = 1000; //keep only contours of a certain size
for (vector<vector<Point> >::iterator it=contours.end(); it!=contours.begin(); it--) {
    if ((*it).size()<minArea || (*it).size()>maxArea) {
        contours.erase(it);
    }
}

drawContours(displayer, contours, a, Scalar(122,200,222),2);

詳細については、こちらを参照してください (特に、検索する輪郭に関するオプションは、検索対象を絞り込むのに役立ちます。私は CV_RETR_EXTERNAL を使用しました)。

フレームのディープ コピー (frame.copyTo(displayer) でコピー) である Mat ディスプレイヤを (前に) 作成したことに注意してください。これは、フレームに直接何かを描画すると、「frameLast」に転送され、次の absDiff でポップアップします. もちろん、描画する前に frame を frameLast にきれいにコピーすることで、この余分な画像を避けることができます (つまり、最後にすべてを描画します), コードのどこからでも簡単に描画できるようにこれを行います.私は多くのことを試していて、時々中間のステップを見たいと思っているので.

于 2012-04-29T09:50:11.283 に答える
0

基本的には、cvBlobsLib を試してみてください。現在使用中です。もちろん、最初は対処するのは非常に困難です。後で慣れると、非常に簡単に使用できます。画像内の白いブロブが検出され、その逆も同様です。その後、境界ボックスを使用できます。そこからポイントの位置を取得できます。

于 2012-05-07T06:43:58.337 に答える