基于opencv的手势识别(HSV)控制鼠标

本文介绍了使用opencv3.4.5和vs2015进行手势识别,并通过识别后的手势来控制鼠标的操作。首先讲解了摄像头的使用,接着阐述了如何定义和读取分类器,用于手势识别。然后,详细讨论了图像处理、滤波技术以及轮廓提取和重心计算的方法。最后,说明了如何将这些步骤结合以实现鼠标控制功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于opencv的手势识别和鼠标控制

opencv3.4.5和vs2015

新建工程->空项目->新建项

摄像头使用

	VideoCapture capture;
	capture.open(0);
	if (!capture.isOpened()){
   //打开失败返回-1
		cout << "No camera!\n" << endl;
		return -1;
	while (1) {
   
			capture >> frame;//刷新
			//Mat frame = imread("1.jpg");  //工程测试
			if (frame.empty())//帧空跳出循环
				break;
			imshow("frame_", frame);
			}
	}

分类器的使用

这里使用了自己做的分类器用作手势识别

定义、读取

	CascadeClassifier open_palm_cascade;
	CascadeClassifier closed_palm_cascade;
	open_palm_cascade.load("palm.xml");
	closed_palm_cascade.load("closed_palm.xml");
	if (open_palm_cascade.empty()) {
   
		cout << "Could not load open_palm configuration file! "
			"Check directory! " << endl << "Press Q to Quit!" << endl;
		while (char(waitKey(0)) != 'q') {
   }
		return -2;
	}
	if (closed_palm_cascade.empty()) {
   
		cout << "Could not load closed_palm configuration file! "
			"Check directory! " << endl << "Press Q to Quit!" << endl;
		while (char(waitKey(0)) != 'q') {
   }
		return -2;
	}

使用

open_palm_cascade.detectMultiScale(frame, open_palms, 1.3, 4, 0, Size(50, 50));
closed_palm_cascade.detectMultiScale(frame, closed_palms, 1.3, 4, 0, Size(50, 50));
			if (closed_palms.size() != 0) {
   
				for (int i = 0; i < closed_palms.size(); i++) {
   
					//cout << "=============Detected a closed_palm!=============" << endl;
					// Top left and bottom right points of rectangle.
					Point closed_palm_rect_p1(closed_palms[i].x, closed_palms[i].y);
					Point closed_palm_rect_p2(closed_palms[i].x + closed_palms[i].width, closed_palms[i].y + closed_palms[i].height);
					// Draw the rectangle in the image.
					rectangle(frame, closed_palm_rect_p1, closed_palm_rect_p2, Scalar(0, 255, 0));
					putText(frame, "Closed Palm", closed_palm_rect_p1, FONT_HERSHEY_SIMPLEX,
						1, Scalar(0, 255, 0), 1, 5, false);
					hand_mode[0] = 1;
				}
			}
			for (int i = 0; i < open_palms.size(); i++) {
   
				//cout << "=============Detected an open_palm!=============" << endl;
				// Top left and bottom right points of rectangle.
				Point open_palm_rect_p1(open_palms[i].x, open_palms[i].y);
				Point open_palm_rect_p2(open_palms[i].x + open_palms[i].width, open_palms[i].y + open_palms[i].height);
				// Draw the rectangle in the image.
				rectangle(frame, open_palm_rect_p1, open_palm_rect_p2, Scalar(255, 0, 0));
				putText(frame, "Open Palm", open_palm_rect_p1, FONT_HERSHEY_SIMPLEX,
					1, Scalar(255, 0, 0), 1, 5, false);
				hand_mode[0] = 2;
			}
			

图像处理、滤波

			medianBlur(frame, frame, 5);
			cvtColor(frame, frame_hsv, CV_BGR2HSV);//转HSV图像
			split(frame_hsv, frameSplit);//三通道图像分离
										 //显示HSV 3通道
										 //imshow("WIN_H", frameSplit[0]);
										 //imshow("WIN_S", frameSplit[1]);
										 //imshow("WIN_V", frameSplit[2]);
										 ///
			Mat dstTemp1(frame.rows, frame.cols, CV_8UC1);
			Mat dstTemp2(frame.rows, frame.cols, CV_8UC1);
			// 对HSV空间进行量化,得到2值图像,亮的部分为手的形状
			inRange(frame_hsv, Scalar(0, 50, 30), Scalar(20, 100, 256), dstTemp1);
			inRange(frame_hsv, Scalar(156, 30, 30), Scalar(180, 170, 256), dstTemp2);
			bitwise_or(dstTemp1, dstTemp2, mask);//按位或
			//imshow("mask", mask);	
			// 形态学操作,去除噪声,并使手的边界更加清晰,提取边缘
			Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));//返回指定形状和尺寸的结构元素,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);
			frame.copyTo(show_img, mask);

轮廓提取、重心计算

			//寻找最外层轮廓  //只保存拐点信息
			findContours(mask, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
			// 去除伪轮廓
			for (size_t i = 0; i < contours.size(); i
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值