【问题标题】:Background Subtraction for hand recognition in OpenCVOpenCV中手部识别的背景减法
【发布时间】:2014-12-06 10:03:33
【问题描述】:

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

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

  1. 部分二值图像问题: 我正在使用 OpenCV 的 MOG2 背景减法方法,它似乎比其他方法效果更好,但我仍然得到了我手的部分二进制图像,如下图所示。我扩大了二值图像以改善其结果并使用medianBlur 进行降噪,但我仍然得到以下结果。我的目标是获得我手部的完整且连续的二进制图像,并且需要有关如何执行此操作的帮助。

二值图像 轮廓来自approxPolyDP 轮廓来自 convexHullapproxPolyDP

  1. 凸面缺陷错误: 出于某种原因,我在尝试查找凸面缺陷时遇到以下错误。

OpenCV 错误:convexityDef 中的断言失败 (hull.checkVector(1, CV_32S) > 2) ects,文件 C:\opencv\modules\imgproc\src\contours.cpp,第 1971 行 在抛出 'cv::Exception' 的实例后调用终止 what(): C:\opencv\modules\imgproc\src\contours.cpp:1971: 错误: (-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;
}

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

【问题讨论】:

    标签: opencv image-processing


    【解决方案1】:

    您为什么不选择 HSV 解决方案?它非常适合肤色检测,还可以去除皮肤背景。

    http://opencv-srf.blogspot.com/2010/09/object-detection-using-color-seperation.html

    当我从事手势识别工作时,该链接有所帮助。

    另一个代码链接:

    http://www.andol.info/hci/1116.htm
    http://answers.opencv.org/question/3300/skin-detection/

    我希望它会有所帮助。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2011-12-19
        • 2016-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-03
        • 2011-12-07
        • 1970-01-01
        相关资源
        最近更新 更多