【问题标题】:OpenCV CvConvexityDefects can't work and can't detect fingers!OpenCV CvConvexityDefects 不能工作,不能检测手指!
【发布时间】:2012-07-29 22:50:04
【问题描述】:

我正在使用 OpenCv 来检测指尖,但现在遇到了一些障碍! findContours & convexHull & convexityDefects 方法不适用于我的项目。 这是我第一次提出问题。谢谢大家!

我的代码如下:

int main()
{
CvScalar white = cvRealScalar(255);
CvScalar black = cvRealScalar(0);

CvSeq* contours = 0;
CvMemStorage* storage = cvCreateMemStorage(0);
IplImage* img = cvLoadImage("h.jpg");
IplImage* imgGray = cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage* contoursImg = cvCreateImage(cvGetSize(img), img->depth, 1);
cvZero(contoursImg);
int nWidth = contoursImg->width;
int nHeight = contoursImg->height;
int nChannels = contoursImg->nChannels;
int nStep = contoursImg->widthStep;
for (int i=0; i<nHeight; i++)
    for(int j=0; j<nWidth; j++)
        contoursImg->imageData[i*nStep + j*nChannels] = 255 - contoursImg->imageData[i*nStep + j*nChannels];

cvCvtColor(img, imgGray, CV_BGR2GRAY);
cvThreshold(imgGray, imgGray, 230, 255, CV_THRESH_BINARY);
cvSmooth(imgGray, imgGray);

cvFindContours(imgGray, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
contours = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 35, 1);
cvDrawContours(contoursImg, contours, CV_RGB(0, 0, 0), CV_RGB(0, 0, 0), 1, 1, 8, cvPoint(0, 0));

CvSeq* hull = cvConvexHull2(contours, 0, CV_CLOCKWISE, 0);
CvSeq* defect = cvConvexityDefects(contours, hull, NULL);
for(; defect; defect = defect->h_next)
{
    int nomdef = defect->total;
    if(!nomdef)
        continue;
    CvConvexityDefect* defectArray = (CvConvexityDefect*)malloc(sizeof(CvConvexityDefect)*nomdef);
    cvCvtSeqToArray(defect, defectArray, CV_WHOLE_SEQ);
    for(int i = 0; i < nomdef; i++)
    {
        cvCircle(contoursImg, *(defectArray[i].end), 5, CV_RGB(255, 0, 0), -1, 8, 0);
        cvCircle(contoursImg, *(defectArray[i].start), 5, CV_RGB(0, 255, 0), -1, 8, 0);
        cvCircle(contoursImg, *(defectArray[i].depth_point), 5, CV_RGB(0, 0, 255), -1, 8, 0);
    }
    free(defectArray);
}

cvNamedWindow("image", 1);
cvShowImage("image", contoursImg);

cvWaitKey(0);
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&imgGray);
cvReleaseImage(&contoursImg);
cvDestroyWindow("image");

return 0;       
}

这是我的手图:

http://www.billwang.net/bbs/oldattach/2006/12/29/billwang_5315954-038-embed.jpg

【问题讨论】:

  • 感谢您编辑我的帖子~ vasile
  • 你的代码对你的形象来说就像一个魅力。我能够生成轮廓图像。你遇到了什么错误?
  • 谢谢你,go4sri。该代码可以生成轮廓图像。但它也应该在指尖产生小黑圈;不幸的是,结果不是我想要的。
  • cvConvexHull2 函数和 cvConvexityDefects 函数和下面的“for”循环应该检测并标记指尖。

标签: opencv convex-hull


【解决方案1】:

这些方法运行良好。您在图像外部检测到一个矩形轮廓。由于这覆盖了整个图像,因此没有缺陷,因此没有检测到。见附图。

【讨论】:

  • 嗯,今天早上我还发现了覆盖整个图像的轮廓(在中国)。我添加了一些代码来清除外部轮廓,并且在使用 convexHull 和凸度缺陷 fncitons 之前只保留手的轮廓。很抱歉,我无法投票赞成您的答案,因为我的代表核心只有一个。非常感谢@go4sri!
  • 非常好的答案...我为这个家伙的答案投了赞成票...如果您可以在此线程本身中分享有关 openCV 中此功能的更多知识,将会非常有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 2012-06-06
  • 2014-03-16
  • 2018-03-17
  • 1970-01-01
相关资源
最近更新 更多