OpenCV中用于手部识别的背景减法
我正在尝试使用OpenCV的背景减法制作一个手势识别程序,但我面临以下问题:手的部分二值图像,以及获得凸面缺陷错误 在发布这个问题之前,我确实在这里查阅了很多帖子,但是没有一个解决方案对我来说是完美的 部分二值图像问题: 我正在使用OpenCV的MOG2背景减法,它似乎比其他方法工作得更好,但我仍然得到我手的部分二值图像,如下图所示。我放大了二值图像以改善其效果,并使用medianBlur进行噪声消除,但仍然得到以下结果。我的目标是得到一个完整的和连续的二进制图像,我的手,需要帮助如何做到这一点。 二值图像 轮廓由approxPolyDP生成 轮廓由convexHull和approxPolyDP生成 凸度缺陷错误: 由于某种原因,我在尝试查找凸性缺陷时遇到以下错误。 OpenCV错误:断言失败hull.checkVector1,凸面定义中的CV_32S>2 ects,文件C:\opencv\modules\imgproc\src\contours.cpp,第1971行 在引发“cv::Exception”的实例后调用terminate 内容:C:\opencv\modules\imgproc\src\contours.cpp:1971:错误:-215 hull.C heckVector1,CV_32S>2函数凸性缺陷 我在不同的地方寻找了一个有效的解决方案,但迄今为止都没有成功 代码OpenCV中用于手部识别的背景减法,opencv,image-processing,Opencv,Image Processing,我正在尝试使用OpenCV的背景减法制作一个手势识别程序,但我面临以下问题:手的部分二值图像,以及获得凸面缺陷错误 在发布这个问题之前,我确实在这里查阅了很多帖子,但是没有一个解决方案对我来说是完美的 部分二值图像问题: 我正在使用OpenCV的MOG2背景减法,它似乎比其他方法工作得更好,但我仍然得到我手的部分二值图像,如下图所示。我放大了二值图像以改善其效果,并使用medianBlur进行噪声消除,但仍然得到以下结果。我的目标是得到一个完整的和连续的二进制图像,我的手,需要帮助如何做到这一点
我将非常感谢您对我的课程提出的任何其他改进建议。您为什么不选择HSV解决方案?这是完美的肤色检测,也消除了皮肤的背景 当我研究手势识别时,这个链接很有帮助 代码的另一个链接:
我希望这会有所帮助。您可以在filterImage函数中增加结构元素的大小,以便将二进制片段连接起来。 另外,尝试直接在二值图像而不是Canny图像上应用FindOntours
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;
}