使用opencv检测黑色背景上的白色物体的矩形

时间:2012-04-28 14:57:52

标签: opencv background-subtraction

我正在使用帧差分和opencv来检测帧之间的移动(absdiff,threshold,erode等)。

如何获取动作的各个位置的坐标(矩形:x,y,宽度,高度),基本上是白色斑点的坐标?

2 个答案:

答案 0 :(得分: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);

有关详细信息,请参阅here(尤其是要查找轮廓的选项,可以帮助您缩小搜索范围。我只使用了CV_RETR_EXTERNAL)。

请注意,我制作了(之前)一个Mat显示器,它是一个框架的深拷贝(用frame.copyTo(显示器)复制。这是因为如果你直接在框架上绘制东西,它将被转移到“ frameLast“并弹出下一个absDiff。当然你可以通过在绘图之前干净地将帧复制到frameLast来避免这个额外的图像(所以最后绘制所有内容),我这样做,所以我可以轻松地从代码中的任何地方绘制,使现在它更容易,因为我正在尝试很多事情,并且希望能够有时看到中间步骤。

答案 1 :(得分:0)

基本上,您可能想尝试cvBlobsLib。目前正在使用它。当然,起初很难处理它。稍后当你习惯它时,使用起来非常简单。它在图像中找到白色斑点,反之亦然。然后你可以使用边界框。从那里你可以得到点位置。

相关问题