更好的video编程边缘滤波算法

我还在研究最后一个程序 ,虽然我终于找到了如何解决问题(关于如何过滤最大轮廓),但我现在有了一个新问题,或者更确切地说是一个问题。

如您所见,我正在使用Canny算法搜索video中的边缘。 但是我将用于检测的对象没有特定的颜色,因此当对象的颜色与周围的颜色大致相同时(例如,如果对象是silverlight并且背景为白色),对象的边缘将消失,我无法获得物体的轮廓。

现在我将测试OpenCV中可用的每个边缘过滤算法,但为了减少我的工作时间,我需要你的帮助来推荐最好的(或至少更好的)算法而不是canny 。 现在我已经测试了Sobel,但结果并不比canny好。 如果可能的话,请链接我一些好的例子以供参考。

代码:

int main( int argc, char** argv ) { CvCapture *cam; CvMoments moments; CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = NULL; CvSeq* contours2 = NULL; CvPoint2D32f center; int i; cam=cvCaptureFromCAM(0); if(cam==NULL){ fprintf(stderr,"Cannot find any camera. \n"); return -1; } while(1){ IplImage *img=cvQueryFrame(cam); if(img==NULL){return -1;} IplImage *src_gray= cvCreateImage( cvSize(img->width,img->height), 8, 1); cvCvtColor( img, src_gray, CV_BGR2GRAY ); cvSmooth( src_gray, src_gray, CV_GAUSSIAN, 5, 11); cvCanny(src_gray, src_gray, 70, 200, 3); cvFindContours( src_gray, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cvPoint(0,0)); if(contours==NULL){ contours=contours2;} contours2=contours; CvSeq* current_contour = contours; double largestArea = 0; CvSeq* largest_contour = NULL; while (current_contour != NULL){ double area = fabs(cvContourArea(current_contour,CV_WHOLE_SEQ, false)); if(area > largestArea){ largestArea = area; largest_contour = current_contour; } current_contour = current_contour->h_next; } cvMoments(largest_contour, &moments, 1); double m_00 = cvGetSpatialMoment( &moments, 0, 0 ); double m_10 = cvGetSpatialMoment( &moments, 1, 0 ); double m_01 = cvGetSpatialMoment( &moments, 0, 1 ); float gravityX = (m_10 / m_00)-150; float gravityY = (m_01 / m_00)-150; if(gravityY>=0&&gravityX>=0&&m_00>=3000){ printf("center point=(%.f, %.f), Area = %.f \n",gravityX,gravityY,m_00); } if(m_00>=3000){ CvScalar color = CV_RGB(250,0,0); cvDrawContours(img,largest_contour,color,color,-1,-1, 8, cvPoint(0,0)); } cvShowImage( "Input", img ); cvShowImage( "Contours", src_gray ); cvClearMemStorage(storage); if(cvWaitKey(33)>=0) break; } cvDestroyWindow("Contours"); cvDestroyWindow("Source"); cvReleaseCapture(&cam); } 

……最后,漫长的等待示例图片:

首先,好的(我的黑钱包) 好的

二,失败(橙色盒子) 失败

最后,另一个失败(白盒子) 白色失败

PS,有些说明:

  • 物体没有特定的形状,颜色或大小,所以IMO最好的办法是找到物体的边缘而不是用颜色过滤它。
  • 我会握住物体,所以也许我的手指会导致物体的边缘改变或消失。
  • 我正在开发一个video处理程序,因此处理时间越短,处理能力越小越好。
  • 我的程序将过滤掉最大的轮廓并用红色填充(见第一张图片)。

提前致谢。 干杯

您的问题不是边缘检测算法。 您的问题是您正在对算法参数进行硬编码,并希望它能够为您投射的所有图像神奇地工作。 此外,在使用cvCanny之前平滑图像是不必要的,因为Canny运算符已经为您执行平滑处理。

由于您现在想要实现的目标更加清晰,我可以提出一个建议:使用video而不是单独查看每个帧。 如果相机是固定的,并且带有物体的手在移动,则通过背景减法检测形状是微不足道的。 如果相机未固定,您仍然可以检测到手 (PDF链接)并从那里开始工作。 此外,使用您可能拥有的任何其他特定于应用程序的知识(例如,项目将位于屏幕中间,手将位于项目下方)。