我使用帧差异和opencv来检测帧之间的移动(absdiff,阈值,侵蚀等)。使用opencv检测黑色背景上的白色物体的矩形
我该如何获得运动的各个位置(矩形:x,y,宽度,高度)的坐标,基本上是白色斑点?
我使用帧差异和opencv来检测帧之间的移动(absdiff,阈值,侵蚀等)。使用opencv检测黑色背景上的白色物体的矩形
我该如何获得运动的各个位置(矩形: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);
见here了解更多详情(特别是选择在其轮廓发现,可以帮助你缩小你发现了什么。我只是用CV_RETR_EXTERNAL)。
请注意,我制作了一个Mat显示器,它是一个frame复制的深层副本(用frame.copyTo(displaysyer)复制),这是因为如果你直接在frame上绘制东西,它会被转移到“frameLast”并弹出下一个absDiff,当然你可以通过在绘制前将frame完全复制到frameLast来避免这个额外的图像(所以最后绘制所有东西),我这样做,这样我就可以从代码中的任何地方轻松绘制,现在更容易,因为我尝试了很多东西,并希望能够有时看到中间步骤。
轮廓尺寸()不是一个区域。它是轮廓中的点数。 – kelin 2016-07-20 16:22:20
基本上,你可能想尝试cvBlobsLib。目前使用它。当然,首先它是非常很难处理它,稍后当你使用它时,使用起来非常简单,它会在图像中找到白斑,副斑反之亦然。那么你可以使用边界框。从那里你可以得到点位置。
您可以先使用'cvFindContour'。然后使用'cvBoundingRect'来解决它。 – 2012-04-28 17:32:39