作为一个OpenCV初学者,为了锻炼能力,决定自己写个手势识别程序,结果比网上找的程序效果还好一些,所以分享出来~~
为了得到更好的效果,我利用了背景减法。取摄像头的第一帧为背景,后面所有帧减去第一帧,这样大量减去了杂质。
比较方法用的matchShapes()函数,这个在之前博客里有介绍,这里就不说了。可以参考https://blog.csdn.net/wangshuai610/article/details/79913600点击打开链接
利用matchShapes()函数得到的返回值,去做判断。
对所有图像做相同处理,二值化处理---->中值滤波--->腐蚀--->膨胀--->查找轮廓,接着把每一帧图像与模板图像用matchShapes()函数进行匹配。最后判断出来结果。完整代码下载链接https://download.csdn.net/my点击打开链接
<textarea readonly="readonly" name="code" class="c++"> void main() { VideoCapture cap(0); if(!cap.isOpened()) //检查打开是否成功 return; Mat frame; Mat background; Mat dst; int count=0; while(1) { cap>>frame; if(!frame.empty()) { count++; if(count==1) background = frame.clone(); //提取第一帧为背景帧 //imshow("video", frame); dst = MoveDetect(background, frame); imshow("result", dst); </textarea>
<textarea readonly="readonly" name="code" class="c++"> //对三个模板进行处理 Mat cloth= imread("cloth.bmp"); cvtColor(cloth, cloth, CV_BGR2GRAY); threshold(cloth, cloth, 40, 255, CV_THRESH_BINARY); vector<vector<Point>> contours1; vector<Vec4i> hierarcy1; findContours(cloth, contours1, hierarcy1, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);</textarea>
<textarea readonly="readonly" name="code" class="c++"> threshold(diff, diff, 70, 255, CV_THRESH_BINARY); //imshow("threshold", diff); Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); Mat element2 = getStructuringElement(MORPH_RECT, Size(10,10)); medianBlur(diff, diff, 5);//滤波参数根据自己环境调整 //imshow("medianBlur", diff); /*blur(diff, diff, Size(10, 10)); imshow("blur", diff);*/ erode(diff, diff, element); //imshow("erode", diff); dilate(diff, diff, element2);//膨胀参数根据自己环境调整 imshow("dilate", diff); vector<vector<Point>> contours; vector<Vec4i> hierarcy; findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找轮廓 //drawContours(result, contours, -1, Scalar(0,0,255), 2, 8); //绘制轮廓 for(int i=0;i<contours.size();i++)//与三个模板分别比较匹配度 { double matchrate1=matchShapes(contours1[0],contours[i],CV_CONTOURS_MATCH_I1, 0.0); cout<<"index1="<<i<<"---"<<setiosflags(ios::fixed)<<matchrate1<<endl; double matchrate2=matchShapes(contours2[0],contours[i],CV_CONTOURS_MATCH_I1, 0.0); cout<<"index2="<<i<<"---"<<setiosflags(ios::fixed)<<matchrate2<<endl; double matchrate3=matchShapes(contours3[0],contours[i],CV_CONTOURS_MATCH_I1, 0.0); cout<<"index3="<<i<<"---"<<setiosflags(ios::fixed)<<matchrate3<<endl; if(matchrate1<matchrate2&&matchrate1<matchrate3) { Mat result= imread("cloth1.jpg"); imshow("jieguo", result); putText(dst, "cloth", Point(30, 70), CV_FONT_HERSHEY_COMPLEX, 2, Scalar(0, 0, 255), 2, 8); } if(matchrate2<matchrate1&&matchrate2<matchrate3) { Mat result= imread("scissors1.jpg"); imshow("jieguo", result); putText(dst, "scissors", Point(30, 70), CV_FONT_HERSHEY_COMPLEX, 2, Scalar(0, 0, 255), 2, 8); } if(matchrate3<matchrate1&&matchrate3<matchrate1) { Mat result= imread("stone1.jpg"); imshow("jieguo", result); putText(dst, "stone", Point(30, 70), CV_FONT_HERSHEY_COMPLEX, 2, Scalar(0, 0, 255), 2, 8); } </textarea>