联合多个手势分类器做的猜拳游戏

经过多天的努力,做出几个分类器然后利用下面代码进行组合调用,虽然效果不是很好,但是已经算是进步了。

 

  1 #define _CRT_SECURE_NO_WARNINGS
  2 //手势检测器测试代码
  3 #include"iostream"
  4 #include"highgui.h"
  5 #include"cv.h"
  6 using namespace std;
  7 //定义全局变量cascase指针(彩色)
  8 CvHaarClassifierCascade* cascade2 = NULL;
  9 CvHaarClassifierCascade* cascade5 = NULL;
 10 CvHaarClassifierCascade* cascade10 = NULL;
 11 //(灰度检测器)
 12 CvHaarClassifierCascade* graycascade2 = NULL;
 13 CvHaarClassifierCascade* graycascade5 = NULL;
 14 CvHaarClassifierCascade* graycascade10 = NULL;
 15 
 16 IplImage* fit = cvLoadImage("F:\\Opencv\\Project\\Codes\\SampleMake\\BetFitGame\\fit.bmp");
 17 IplImage* hand = cvLoadImage("F:\\Opencv\\Project\\Codes\\SampleMake\\BetFitGame\\hand.bmp");
 18 IplImage* sci = cvLoadImage("F:\\Opencv\\Project\\Codes\\SampleMake\\BetFitGame\\scisor.bmp");
 19 IplImage* jpg = cvLoadImage("F:\\Opencv\\Project\\Codes\\SampleMake\\BetFitGame\\none.bmp");
 20 //要加载的分类器全路径(有色)
 21 char str5[] = "F:\\Opencv\\detector\\color\\colorhand5cascade.xml";
 22 char str2[] = "F:\\Opencv\\detector\\color\\colorhand2\\name.xml";
 23 char str10[] = "F:\\Opencv\\detector\\color\\colorhand10cascade.xml";
 24 //(灰度检测器)
 25 char graystr2[] = "F:\\Opencv\\detector\\gray\\grayhand2\\name.xml";
 26 char graystr5[] = "F:\\Opencv\\detector\\gray\\grayhand5cascade.xml";
 27 char graystr10[] = "F:\\Opencv\\detector\\gray\\grayhand10cascade.xml";
 28 
 29 CvCapture* capture = NULL;
 30 //设置三个内存,检测的时候使用
 31 CvMemStorage* storage2 = cvCreateMemStorage(0);
 32 CvMemStorage* storage5 = cvCreateMemStorage(0);
 33 CvMemStorage* storage10 = cvCreateMemStorage(0);
 34 //灰度
 35 CvMemStorage* graystorage2 = cvCreateMemStorage(0);
 36 CvMemStorage* graystorage5 = cvCreateMemStorage(0);
 37 CvMemStorage* graystorage10 = cvCreateMemStorage(0);
 38 //定义三个全局变量的序列,储存获得的轮廓
 39 CvSeq* seq2 = 0;
 40 CvSeq* seq5 = 0;
 41 CvSeq* seq10 = 0;
 42 //灰度
 43 CvSeq* grayseq2 = 0;
 44 CvSeq* grayseq5 = 0;
 45 CvSeq* grayseq10 = 0;
 46 //定义三个指针类型的矩形变量
 47 CvRect* rect2 = NULL;
 48 CvRect* rect5 = NULL;
 49 CvRect* rect10 = NULL;
 50 //灰度
 51 CvRect* grayrect2 = NULL;
 52 CvRect* grayrect5 = NULL;
 53 CvRect* grayrect10 = NULL;
 54 
 55 //设定缩放比例
 56 double scale = 3;
 57 //定义三张小图片,供转换后检测使用
 58 IplImage* simg2 = NULL;
 59 IplImage* simg5 = NULL;
 60 IplImage* simg10 = NULL;
 61 //灰度
 62 IplImage* graysimg2 = NULL;
 63 IplImage* graysimg5 = NULL;
 64 IplImage* graysimg10 = NULL;
 65 void LoadDetector()//加载分类器
 66 {
 67     //加载分类器(彩色)
 68     try{ cascade2 = (CvHaarClassifierCascade*)cvLoad(str2); }
 69     catch (cv::Exception){ cout << "加载分类器" << str2 << "出现错误" << endl; exit(0); }
 70     try{ cascade10 = (CvHaarClassifierCascade*)cvLoad(str10); }
 71     catch (cv::Exception){ cout << "加载分类器" << str10 << "出现错误" << endl; exit(0); }
 72     try{ cascade5 = (CvHaarClassifierCascade*)cvLoad(str5); }
 73     catch (cv::Exception){ cout << "加载分类器" << str5 << "出现错误" << endl; exit(0); }
 74     //灰度
 75     try{ graycascade2 = (CvHaarClassifierCascade*)cvLoad(graystr2); }
 76     catch (cv::Exception){ cout << "加载分类器" << graystr2 << "出现错误" << endl; exit(0); }
 77     try{ graycascade5 = (CvHaarClassifierCascade*)cvLoad(graystr5); }
 78     catch (cv::Exception){ cout << "加载分类器" << graystr5 << "出现错误" << endl; exit(0); }
 79     try{ graycascade10 = (CvHaarClassifierCascade*)cvLoad(graystr10); }
 80     catch (cv::Exception){ cout << "加载分类器" << graystr10 << "出现错误" << endl; exit(0); }
 81 }
 82 void InitialSmallPicture(IplImage* img)
 83 {
 84     //获取原图像大小
 85     CvSize size = cvGetSize(img);
 86     //缩放后的图像
 87     CvSize smallsize = cvSize(1.0*size.width / scale, 1.0*size.height / scale);
 88     //根据原图像和新尺寸创建新的图片,用来检测,可以提高检测速度
 89     simg2 = cvCreateImage(smallsize, img->depth, img->nChannels);
 90     simg5 = cvCreateImage(smallsize, img->depth, img->nChannels);
 91     simg10 = cvCreateImage(smallsize, img->depth, img->nChannels);
 92     graysimg2 = cvCreateImage(smallsize, 8, 1);
 93     graysimg5 = cvCreateImage(smallsize, 8, 1);
 94     graysimg10 = cvCreateImage(smallsize, 8, 1);
 95 }
 96 void DetectObject(IplImage* img)
 97 {
 98     //将所有的照片按比例缩小
 99     cvResize(img, simg2);
100     cvResize(img, simg5);
101     cvResize(img, simg10);
102     //转化给灰度一些
103     cvCvtColor(simg2, graysimg2, CV_BGR2GRAY);
104     cvCvtColor(simg5, graysimg5, CV_BGR2GRAY);
105     cvCvtColor(simg10, graysimg10, CV_BGR2GRAY);
106     //初始化所有的矩阵变量
107     rect2 = NULL;
108     rect5 = NULL;
109     rect10 = NULL;
110     grayrect2 = NULL;
111     grayrect5 = NULL;
112     grayrect10 = NULL;
113 
114     if (storage2){ cvClearMemStorage(storage2); }
115     if (storage5){ cvClearMemStorage(storage5); }
116     if (storage10){ cvClearMemStorage(storage10); }
117     if (graystorage2){ cvClearMemStorage(graystorage2); }
118     if (graystorage5){ cvClearMemStorage(graystorage5); }
119     if (graystorage10){ cvClearMemStorage(graystorage10); }
120     //检测函数
121 
122     //color2
123     seq2 = cvHaarDetectObjects(simg2, cascade2, storage2, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
124     if (seq2&&seq2->total > 0)
125     {
126         rect2 = (CvRect*)cvGetSeqElem(seq2, 0);
127         return;
128     }
129     //gray2
130     grayseq2 = cvHaarDetectObjects(graysimg2, graycascade2, graystorage2, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
131     if (grayseq2&&grayseq2->total > 0)
132     {
133         grayrect2 = (CvRect*)cvGetSeqElem(grayseq2, 0);
134         //if (rect2)
135         return;
136     }
137 
138     //color5
139     seq5 = cvHaarDetectObjects(simg5, cascade5, storage5, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, cvSize(6, 10), cvSize(140, 200));
140     if (seq5&&seq5->total > 0)
141     {
142         rect5 = (CvRect*)cvGetSeqElem(seq5, 0);
143         //rect2 = NULL;
144         //grayrect2 = NULL;
145         //return;
146     }
147     //gray5
148     grayseq5 = cvHaarDetectObjects(graysimg5, graycascade5, graystorage5, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, cvSize(6, 10), cvSize(140, 200));
149     if (rect5&&grayseq5->total > 0)
150     {
151         grayrect5 = (CvRect*)cvGetSeqElem(grayseq5, 0);
152 
153         rect2 = NULL;
154         grayrect2 = NULL;
155         if (1.0*rect5->height / grayrect5->width > 1.5)
156         {
157             return;
158         }
159         else
160         {
161             grayrect5 = NULL;
162             rect5 = NULL;
163         }
164     }
165     //color10
166     seq10 = cvHaarDetectObjects(simg10, cascade10, storage10, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT,cvSize(1,1));
167     if (seq10&&seq10->total > 0)
168     {
169         rect10 = (CvRect*)cvGetSeqElem(seq10, 0);
170         return;
171     }
172     //gray10
173     grayseq10 = cvHaarDetectObjects(graysimg10, graycascade10, graystorage10, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, cvSize(5, 5));
174     if (grayseq10&&grayseq10->total>0)
175     {
176         grayrect10 = (CvRect*)cvGetSeqElem(grayseq10, 0);
177         return;
178     }
179 }
180 int index2 = 0;
181 int index5 = 0;
182 int index10 = 0;
183 void drawrectangele(IplImage* image)
184 {
185     if (rect2 || grayrect2)
186     {
187         index2++;
188         if (index5 >= 1)index5--;
189         else index5 = 0;
190         if (index10 >= 1)index10--;
191         else index10 = 0;
192         if (index2 >= 1){
193             index5 = 0;
194             index10 = 0;
195             index2--;
196             if (!rect2)rect2 = grayrect2;
197             cvRectangle(image, cvPoint(rect2->x*scale, scale*rect2->y), cvPoint((rect2->x + rect2->width)*scale, (rect2->y + rect2->height)*scale), cvScalarAll(0), 2);
198             cvPutText(image, "find scissor inside picture!", cvPoint(30, 80), &cvFont(2, 1), cvScalarAll(0));
199             cvShowImage("BetGame", fit);
200             return;
201         }
202     }
203     if (rect10 || grayrect10)
204     {
205         index10++;
206         if (index5 >= 1)index5--;
207         else index5 = 0;
208         if (index2 >= 1)index2--;
209         else index2 = 0;
210         if (index10 >= 7){
211             index2 = 0;
212             index5 = 0;
213             index10--;
214             if (!rect10)rect10 = grayrect10;
215             cvRectangle(image, cvPoint(rect10->x*scale, scale*rect10->y), cvPoint((rect10->x + rect10->width)*scale, (rect10->y + rect10->height)*scale), cvScalarAll(0), 2);
216             cvPutText(image, "Find fit inside picture!", cvPoint(30, 80), &cvFont(2, 1), cvScalarAll(0));
217             cvShowImage("BetGame", hand);
218             return;
219         }
220     }
221     if (rect5||grayrect5)
222     {
223         index5++;
224         if (index10 >= 1)index10--;
225         else index10 = 0;
226         if (index2 >= 1)index2--;
227         else index2 = 0;
228         if (index5 >=2){
229             index10 = 0;
230             index2 = 0;
231             index5--;
232             if (!rect5)rect5 = grayrect5;
233             cvRectangle(image, cvPoint(rect5->x*scale, scale*rect5->y), cvPoint((rect5->x + rect5->width)*scale, (rect5->y + rect5->height)*scale), cvScalarAll(0), 2);
234             cvPutText(image, "Find hand inside picture!", cvPoint(30, 80), &cvFont(2, 1), cvScalarAll(0));
235             cvShowImage("BetGame", sci);
236             return;
237         }
238     }
239     
240     cvPutText(image, "Not find anything inside picture!", cvPoint(30, 80), &cvFont(2, 1), cvScalarAll(0));
241     cvShowImage("BetGame", jpg);
242 }
243 int main()
244 {
245     LoadDetector();
246     //打开摄像头
247     try{ capture = cvCreateCameraCapture(0); }
248     catch (cv::Exception){ cout << "打开摄像头出错" << endl; exit(0); }
249     //定义新图片,并用capture初始化
250     IplImage* image = cvQueryFrame(capture);
251     InitialSmallPicture(image);
252     //命名窗口
253     cvNamedWindow("Detector Runing");
254     cvNamedWindow("BetGame");
255 
256     while (true)
257     {
258         //循环获取图片
259         image = cvQueryFrame(capture);
260         //检测器运行
261         if (image)
262         {
263             DetectObject(image);
264             drawrectangele(image);
265         }
266         cvShowImage("Detector Runing", image);
267         //如果按下ESC键就退出循环(ESC键值是27)
268         if (cvWaitKey(20) == 27)break;
269     }
270     cvReleaseCapture(&capture);
271     cvDestroyAllWindows();
272     return 0;
273 }

 

说明:对摄像头伸出拳头,则反馈手掌;伸出双指(剪刀),反馈拳头;伸出手掌,反馈剪刀。

posted @ 2015-01-24 01:54  SYTM  阅读(796)  评论(0编辑  收藏  举报