opencv手势识别——来和电脑玩剪刀石头布

代码超级乱啊,以后有时间再整理了

#include <iostream>    // for standard I/O
#include <string>   // for strings
#include <iomanip>  // for controlling float print precision
#include <sstream>  // string to number conversion
#include <cmath> 
#include <cstdlib> 
#include <opencv2/imgproc/imgproc.hpp>  // Gaussian Blur
#include <opencv2/core/core.hpp>        // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/highgui/highgui.hpp>  // OpenCV window I/O

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
	const std::string sourceReference = "test3.avi";
	int delay = 500;

	char c;
	int frameNum = -1;            // Frame counter

	VideoCapture captRefrnc(0);
	VideoCapture captRefrnc0(1);

	if (!captRefrnc.isOpened())
	{
		return -1;
	}

	Size refS = Size((int)captRefrnc.get(CV_CAP_PROP_FRAME_WIDTH),
		(int)captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT));

	bool bHandFlag = false;

	const char* WIN_SRC = "Source";
	const char* WIN_RESULT = "Result";
	const char* R_HAND = "R_HAND";
	// Windows
	namedWindow(WIN_SRC, CV_WINDOW_AUTOSIZE);
	namedWindow(WIN_RESULT, CV_WINDOW_AUTOSIZE);

	Mat frame;    // 输入视频帧序列
	Mat frameHSV;    // hsv空间
	Mat mask(frame.rows, frame.cols, CV_8UC1);    // 2值掩膜
	Mat dst(frame);    // 输出图像

//     Mat frameSplit[4];

	vector< vector<Point> > contours;    // 轮廓
	vector< vector<Point> > filterContours;    // 筛选后的轮廓
	vector< Vec4i > hierarchy;    // 轮廓的结构信息
	vector< Point > hull;    // 凸包络的点集
	Mat r_hand0 = imread("6.jpg");
	Mat r_hand1 = imread("5.jpg");
	Mat r_hand2 = imread("4.jpg");
	Mat win = imread("win.jpg");
	Mat lose = imread("lose.jpg");
	Mat ping = imread("ping.jpg");
	namedWindow("r");
	while (true) 
	{
		
		vector< Point > hull_point;
		captRefrnc >> frame;

		if (frame.empty())
		{
			cout << " < < <  Game over!  > > > ";
			break;
		}
		

		medianBlur(frame, frame, 5);
		
		cvtColor(frame, frameHSV, CV_BGR2HSV);
		Mat dstTemp1(frame.rows, frame.cols, CV_8UC1);
		Mat dstTemp2(frame.rows, frame.cols, CV_8UC1);
		// 对HSV空间进行量化,得到2值图像,亮的部分为手的形状
		inRange(frameHSV, Scalar(0, 30, 30), Scalar(30, 170, 256), dstTemp1);
		inRange(frameHSV, Scalar(156, 30, 30), Scalar(180, 170, 256), dstTemp2);
		bitwise_or(dstTemp1, dstTemp2, mask);
		//         inRange(frameHSV, Scalar(0,30,30), Scalar(180,170,256), dst);        

				// 形态学操作,去除噪声,并使手的边界更加清晰
		Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
		erode(mask, mask, element);
		morphologyEx(mask, mask, MORPH_OPEN, element);
		dilate(mask, mask, element);
		morphologyEx(mask, mask, MORPH_CLOSE, element);

		frame.copyTo(dst, mask);

		contours.clear();
		hierarchy.clear();
		filterContours.clear();
		// 得到手的轮廓
		findContours(mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
		// 去除伪轮廓
		for (size_t i = 0; i < contours.size(); i++)
		{
			if (fabs(contourArea(Mat(contours[i]))) > 30000)    //判断手进入区域的阈值
			{
				filterContours.push_back(contours[i]);
			}
		}
		// 画轮廓
		drawContours(dst, filterContours, -1, Scalar(0, 0, 255), 3/*, 8, hierarchy*/);
		// 得到轮廓的凸包络
        //去除相邻比较近的点
		for (size_t j = 0; j < filterContours.size(); j++)
		{
			convexHull(Mat(filterContours[j]), hull, true);
			int hullcount = (int)hull.size();
			for (int i = 0; i < hull.size(); i++) {
				for (int j = (i+1); j < hull.size(); j++) {
					double dist = sqrt(pow((hull[i].x-hull[j].x),2) + pow((hull[i].y - hull[j].y), 2));
					if (dist < 150) {
						hull[j].x = 0;
						hull[j].y = 0;
					}
				}
			}
			int t = 0;
			for (int i = 0; i < hull.size(); i++) {
				if (hull[i].x > 0 && hull[i].y > 0) {
					t++;
				}
			}
            
            //剪刀石头布
            //0石头,1剪刀,2布

			cout << t << endl;
			if (t == 3) {
				t -= 3;
				putText(frame, "You: Stone", Point(100, 100), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2);
			}
			else if(t == 4) {
				t -= 3;
				putText(frame, "You: shears", Point(100, 100), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2);
			}
			else if (t == 5) {
				t -= 3;
				putText(frame, "You: cloth", Point(100, 100), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2);
			}

			int robot = rand()%(3-0) + 0;
			cout << robot << endl;
			
			if (robot == 0) {
				imshow(R_HAND, r_hand0);
				putText(r_hand0, "Robot: Stone", Point(50, 100), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
			}
			else if (robot == 1) {
				imshow(R_HAND, r_hand1);
				putText(r_hand1, "Robot: shears", Point(50, 100), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
			}
			else if (robot == 2) {
				imshow(R_HAND, r_hand2);
				putText(r_hand2, "Robot: cloth", Point(50, 100), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
			}

			if (t == 0) {
				if (robot == 0) {
					imshow("r", ping);
				}
				else if (robot == 1) {
					imshow("r", win);
				}
				else if (robot == 2) {
					imshow("r", lose);
				}
			}
			if (t == 1) {
				if (robot == 1) {
					imshow("r", ping);
				}
				else if (robot == 2) {
					imshow("r", win);
				}
				else if (robot == 0) {
					imshow("r", lose);
				}
			}
			if (t == 2) {
				if (robot == 2) {
					imshow("r", ping);
				}
				else if (robot == 0) {
					imshow("r", win);
				}
				else if (robot == 1) {
					imshow("r", lose);
				}
			}

			int size = 0;
			for (size = 0; size < hullcount - 1; size++)
			{
				if (hull[size].x > 0 && hull[size].y > 0) {
					line(dst, hull[size + 1], hull[size], Scalar(255, 0, 0), 2, CV_AA);
				}
			}
			if (hull[size].x > 0 && hull[size].y > 0) {
				line(dst, hull[hullcount - 1], hull[0], Scalar(255, 0, 0), 2, CV_AA);
			}

		}

		imshow(WIN_RESULT, dst);
		
		dst.release();
		// End
		imshow(WIN_SRC, frame);
		c = cvWaitKey(delay);
		if (c == 27) break;
		destroyWindow("r");
	}
}

 

 

 下面的图片素材可自行百度下载,这里就不提供了

 

猜你喜欢

转载自blog.csdn.net/qq_40238526/article/details/90299120