代码超级乱啊,以后有时间再整理了
#include // for standard I/O
#include // for strings
#include // for controlling float print precision
#include // string to number conversion
#include
#include
#include // Gaussian Blur
#include // Basic OpenCV structures (cv::Mat, Scalar)
#include // 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 > contours; // 轮廓
vector< vector > 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");
}
}
下面的图片素材可自行百度下载,这里就不提供了