我现在正在工作的程序几乎完成了,但我对结果不是很满意。通过使用 Canny 算法,我设法非常清楚地了解了对象的轮廓,但是程序在识别轮廓并用红线绘制轮廓时存在一些问题。该程序:
void setwindowSettings(){
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
createTrackbar("LowerC", "Contours", &lowerC, 255, NULL);
createTrackbar("UpperC", "Contours", &upperC, 255, NULL);
}
void wait(void)
{
long t=30000000;
while(t--);
}
int main(void)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat frame,foreground,image;
double pt1, pt2, area;
Rect rect;
int i;
vector<vector<Point> > contours;
vector<vector<Point> > largest_contours;
namedWindow("Capture", CV_WINDOW_AUTOSIZE);
setwindowSettings();
while(1){
cap >> frame; // get a new frame from camera
if( frame.empty() )
break;
image=frame.clone();
cvtColor(image,foreground,CV_BGR2GRAY);
GaussianBlur(foreground,foreground,Size(9,11),0,0);
Canny(foreground,foreground,lowerC,upperC,3);
findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
if(contours.empty())
continue;
double largest_area = 0;
for( i= 0; i < contours.size(); i++){ // get the largest contour
area = fabs(contourArea(contours[i]));
if(area >= largest_area){
largest_area = area;
largest_contours.clear();
largest_contours.push_back(contours[i]);
}
}
if(largest_area>=3000){ // draw the largest contour if exceeded minimum largest area
drawContours(image,largest_contours,-1,Scalar(0,0,255),2);
printf("area = %.f\n",largest_area);
}
wait();
imshow( "Capture",image );
imshow("Contours",foreground);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
节目摘要:
- 从相机获取图像
- 噪声过滤(转换为灰色→模糊→Canny)
- 寻找轮廓
- 找到图像中最大的轮廓及其区域,即对象
- 在物体周围画一条红线,打印出最大的区域
- 冲洗并重复
结果:
我很少得到我想要的;检测到轮廓,绘制红线(GOOD ONE):
...通常我得到这个;未检测到轮廓,未检测到红线(BAD ONE):
获得GOOD ONE的机会1/20
不是很好。Contours
此外,当物体周围出现红线时,屏幕中物体的轮廓线会闪烁(参见 GOOD ONE 图片)。我正在使用我的一个对象(一个黑色的小方块)来回答这个问题,但请注意,此对象检测程序的主要目标是检测对象,无论其形状或颜色如何。
所以我的问题是:
- 尽管轮廓清晰如初,为什么我仍然会得到 BAD ONES?
- 任何人都可以分享关于如何改进轮廓检测的更好的想法吗?(即更好的模糊算法)
在物体周围画红线时,如何避免轮廓线闪烁?
编辑:我刚刚发现轮廓线闪烁不是因为它周围绘制的红线(使用drawContours
或line
函数),而是在findContours
函数检测到最大轮廓并计算为最大轮廓之后发生。
关于没有的问题。3 单击此处。视频在这里,点击它!!!
提前致谢。
PS:我在 Visual C++ 2010 Exp 女士上使用 OpenCV 2.4.3。