使用opencv在黑色背景上检测白色对象的矩形

使用opencv在黑色背景上检测白色对象的矩形,opencv,background-subtraction,Opencv,Background Subtraction,我使用帧差分和opencv来检测帧之间的移动(absdiff、threshold、腐蚀等) 我如何获得运动的各个位置的坐标(矩形:x,y,宽度,高度),基本上是白色斑点的坐标?我也在做同样的事情。这是我的代码(有些事情在不同的类中处理,我只是把它们放在一起)。第一部分是您已经拥有的,跳到轮廓部分 /* This is the background subtraction you already have */ Mat tmp1; GaussianBlur( frame, tmp1, Size(5

我使用帧差分和opencv来检测帧之间的移动(absdiff、threshold、腐蚀等)


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

我也在做同样的事情。这是我的代码(有些事情在不同的类中处理,我只是把它们放在一起)。第一部分是您已经拥有的,跳到轮廓部分

/* 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);
/*这是您已有的背景减法*/
Mat-tmp1;
高斯模糊(帧,tmp1,大小(5,5),0,0)//模糊一幅图像就足以消除噪声
absdiff(tmp1,最后一帧,tmp1);
CVT颜色(tmp1、tmp1、CV_rgb2灰色);
阈值(tmp1、tmp1、CV_-THRESH_-OTSU、100、CV_-THRESH_-BINARY);
/*清理*/
int\u type=MORPH\u RECT;//变形直线、变形交叉、变形椭圆
国际单位面积=3;
Mat侵蚀元素=getStructuringElement(侵蚀类型、大小(2*侵蚀大小+1、2*侵蚀大小+1)、点(侵蚀大小、侵蚀大小));
整数膨胀类型=变形类型;
int膨胀_大小=5;
Mat DILLATION_元素=getStructuringElement(DILLATION_类型,大小(2*DILLATION_大小+1,2*DILLATION_大小+1),点(DILLATION_大小,DILLATION_大小));
侵蚀(tmp1、tmp1、侵蚀_元件);
扩张(tmp1,tmp1,扩张单元);
/*这里我得到了轮廓*/
矢量等值线;
findContours(tmp1、等高线、等高线、等高线、等高线、等高线链、等高线近似简单);
int minArea=100,maxArea=1000//只保留一定大小的轮廓
对于(vector::iterator it=contours.end();it!=contours.begin();it--){
if((*it).size()最大面积){
删除(它);
}
}
绘制等高线(显示器,等高线,a,标量(122200222),2);
有关更多详细信息,请参见(特别是要查找的轮廓选项,可以帮助您缩小查找范围。我刚刚使用了CV_RETR_EXTERNAL)


请注意,我(之前)制作了一个Mat displayer,它是frame的深度副本(使用frame.copyTo(displayer)复制)。这是因为如果您直接在frame上绘制内容,它将被传输到“frameLast”并在下一个absDiff中弹出。当然,您可以通过在绘制之前将frame清晰地复制到frameLast来避免这个额外的图像(因此,在末尾绘制所有内容),我这样做是为了可以轻松地从代码中的任何位置进行绘制,这使得现在的绘制变得更容易,因为我正在尝试很多事情,并且希望能够不时看到中间步骤。

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

你可以先使用
cvFindContour
。然后使用
cvBoundingRect
围绕它进行矩形。轮廓大小()不是一个区域。它是轮廓中的点数。