我现在正在工作的程序是almost完成了,但我对结果不是很满意。通过使用 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”图片)。
我正在使用我的一个对象(一个小黑色方框)来回答这个问题,但请注意,该对象检测程序的主要目标是检测物体,无论其形状或颜色如何。
所以我的问题是:
- 尽管轮廓清晰如日,为什么我还是得到了坏的?
- 谁能分享关于如何改进轮廓检测的更好想法? (即更好的模糊算法)
- 当在物体周围绘制红线时,如何避免轮廓线闪烁?