2014-10-11 129 views
1

我正在尝试使用OpenCV的背景减法方法来制作手势识别程序,但我面临以下问题,手部分二值化图像,并且出现了凸面缺陷错误。OpenCV中手部识别的背景减法

在发布这个问题之前,我没有在这里查找各种帖子,但没有一个解决方案为我完美工作。

  1. 部分二值图像的问题: 我使用的OpenCV的MOG2背景扣除方法,似乎工作比其他方法更好,但我仍然得到我的手的部分二进制图像,如图下图。我扩大了二进制图像,以改善其结果,并使用medianBlur进行噪音消除,但仍得到以下结果。我的目标是获得我的手的完整和连续的二进制图像,并需要帮助如何做到这一点。

二值图像 enter image description here 轮廓从approxPolyDP enter image description here 轮廓导致convexHullapproxPolyDP enter image description here

导致
  • 凸缺陷错误: 出于某种原因,我正在尝试查找凸面缺陷时出现以下错误。
  • OpenCV Error: Assertion failed (hull.checkVector(1, CV_32S) > 2) in convexityDef ects, file C:\opencv\modules\imgproc\src\contours.cpp, line 1971 terminate called after throwing an instance of 'cv::Exception' what(): C:\opencv\modules\imgproc\src\contours.cpp:1971: error: (-215) hull.c heckVector(1, CV_32S) > 2 in function convexityDefects

    我已经在不同的地方抬起头来寻找工作的解决方案,但一直不成功至今。

    代码

    using namespace std; 
    using namespace cv; 
    
    int lH =0; 
    int lS =0; 
    int lV =0; 
    int uH = 180; 
    int uS = 255; 
    int uV = 255; 
    
    void filterImage(Mat &img) 
    { 
    Mat erodeElement = getStructuringElement(MORPH_RECT,Size(2,2)); 
    Mat dilateElement = getStructuringElement(MORPH_RECT,Size(5,5)); 
    
    //erode(img,img,erodeElement); 
    dilate(img,img,dilateElement); 
    dilate(img,img,dilateElement); 
    } 
    
    int main() 
    { 
    Mat frame(600,600,CV_8UC3); 
    Mat fgMaskMog2(600,600,CV_8UC1); 
    Mat refinedimg(600,600,CV_8UC1); 
    namedWindow("frameOutput",CV_WINDOW_AUTOSIZE); 
    namedWindow("Mog2Output",CV_WINDOW_AUTOSIZE); 
    namedWindow("out",CV_WINDOW_AUTOSIZE); 
    
    BackgroundSubtractorMOG2 MOG2; 
    BackgroundSubtractorMOG MOG; 
    
    VideoCapture cap(0); 
    
    //contours variables 
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
    
    
    while(1) 
    { 
        cap>>frame; 
        flip(frame,frame,1); 
    
        MOG2(frame,fgMaskMog2); 
    
        filterImage(fgMaskMog2); 
        medianBlur(fgMaskMog2,fgMaskMog2,15); 
    
        Canny(fgMaskMog2,refinedimg,50,200,3); 
        findContours(refinedimg,contours,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0)); 
        vector<vector<Point> > hull(contours.size()); 
        vector<vector<int> > hulldf(contours.size()); 
        vector<vector<Point> > contours_poly(contours.size()); 
        vector<vector<Vec4i> > defects(contours.size()); 
        for(int j=0;j < contours.size();j++) 
        { 
         approxPolyDP(contours[j],contours_poly[j],5,true); 
        } 
        for(int k=0;k<contours.size();k++) 
        { 
         convexHull(contours_poly[k],hull[k],false); 
         convexHull(contours_poly[k],hulldf[k],false); 
         if(hulldf.size()>3) 
         { 
          convexityDefects(contours[k],hulldf[k],defects[k]); 
         } 
        } 
    
        for(int i=0;i<contours.size();i++) 
        { 
         drawContours(frame, contours_poly, i, Scalar(0,255,0), 2, 8, hierarchy, 0, Point()); 
         drawContours(frame, hull, i,Scalar(255,0,0),2,8, hierarchy,0,Point()); 
        } 
    
        imshow("frameOutput",frame); 
        imshow("Mog2Output",fgMaskMog2); 
        imshow("out",refinedimg); 
    
        int c = waitKey(31); 
        if(c==27) 
         break; 
    } 
    return 0; 
    } 
    

    我将不胜感激改进我的这个程序的任何其他额外的建议。

    回答

    0

    您可以增加filterImage()函数中结构元素的大小,以便连接二进制碎片。
    此外,尝试直接应用findContours()二进制图像,而不是Canny图像。