基于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

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

被折叠的 条评论
为什么被折叠?



