首页 > 编程语言 >20个基础到进阶版的OpenCV4.9.0趣味项目(C++版)(八)——石头、剪刀、布识别手势识别(传统方法)

20个基础到进阶版的OpenCV4.9.0趣味项目(C++版)(八)——石头、剪刀、布识别手势识别(传统方法)

时间:2024-10-24 14:20:34浏览次数:9  
标签:缺陷 20 进阶 frame 凸包 contours 识别 手势 cv

20个基础到进阶版的OpenCV4.9.0趣味项目(C++版)(八)——石头、剪刀、布识别手势识别(传统方法)

文章目录

一、引言

手势识别是一种通过图像或视频分析来识别和理解人手姿态的技术。它在虚拟现实、增强现实、游戏控制等领域有着广泛的应用。本文将基于OpenCV,通过C++代码实现一个简单的手势识别系统,能够识别出用户做出的石头、剪刀、布手势。

二、核心知识

1.YCrCb空间转换和提取

在这里插入图片描述

1)YCrCb色彩空间:

YCrCb色彩空间是一种亮度-色度模型,其中Y表示亮度分量,Cr和Cb表示色度分量。这种色彩空间广泛应用于视频编码中,因为它可以有效地将图像信息分解为亮度和色度分量,从而简化处理过程并提高效率。

Y分量: 表示图像的亮度信息,其取值范围为0到255。亮度分量反映了图像中每个像素的明暗程度。
Cr分量: 表示图像的红色色度信息,其取值范围为-128到127。红色色度分量反映了图像中红色成分与亮度的差异。
Cb分量: 表示图像的蓝色色度信息,其取值范围同样为-128到127。蓝色色度分量反映了图像中蓝色成分与亮度的差异。

2)分割:

利用Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。
步骤:
(1)将RGB图像转换到YCrCb颜色空间,提取Cr分量图像
(2)对Cr做自二值化阈值分割处理(Otsu法)

2.凸包

在这里插入图片描述

凸包(Convex Hull)是计算几何中的一个重要概念。在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。在二维欧几里得空间中,凸包可以想象为一条刚好包住所有点的橡皮圈,或者用不严谨的话来说,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。

凸包计算原理:

OpenCV中计算凸包的具体算法并没有在官方文档中明确说明,但通常使用的是一些经典的凸包算法,如Graham扫描法、Jarvis步进法或QuickHull算法。这些算法的核心思想是通过迭代的方式,逐步确定凸包的顶点。以下是这些算法的基本步骤:

1)点集排序: 首先选择一个参考点(通常是横坐标最小的点),然后按照极角对点集进行排序。这样可以确保后续处理时点的顺序是合理的。
2)初始化凸包: 将排序后的第一个点和第二个点加入凸包。
3)扫描点集: 从第三个点开始,依次扫描点集。对于每个点,判断它与凸包上的最后两个点构成的线段的关系(左转、右转或共线)。如果是左转,说明该点位于凸包上,将其加入凸包;如果是右转或共线,说明该点不在凸包上,忽略它。
4)更新凸包: 不断重复扫描点集的步骤,直到扫描完所有点。最终得到的凸包就是包含所有点的最小凸多边形。

3.凸缺陷

凸缺陷(Convexity Defects)是指一组点在其凸包(Convex Hull)和形状之间的偏差部分。简单来说,凸缺陷描述了物体轮廓与其凸包之间的凹陷区域。凸包是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点,而凸缺陷则是这个凸多边形与物体实际轮廓之间的“空隙”。

凸缺陷计算原理:

在这里插入图片描述

在OpenCV中,凸缺陷的计算是基于凸包检测的结果进行的。首先,使用cv2.convexHull函数计算给定点集的凸包。然后,通过比较凸包与原始轮廓之间的差异,可以确定凸缺陷的位置和特征。

具体来说,凸缺陷的计算涉及以下几个步骤:
1)凸包检测: 使用cv::convexHull函数计算给定点集的凸包。
2)轮廓与凸包比较: 遍历原始轮廓上的每个点,计算其与凸包之间的距离和位置关系。
3)凸缺陷识别: 根据轮廓点与凸包之间的距离和位置关系,识别出凸缺陷的起始点、终止点和最远点。
4)凸缺陷特征提取: 提取凸缺陷的深度、长度等特征信息,用于后续的图像分析和处理。

4.Otsu法阈值分割

在这里插入图片描述

Otsu法的基本思想是通过遍历所有可能的阈值,将图像分割为前景(目标)和背景两部分,使得这两部分之间的类间方差最大(或等价地,类内方差最小)。这个最佳的灰度级别即被选为分割阈值。

算法步骤:

1)计算图像的直方图: 直方图表示图像中每个灰度级别的像素数量。
2)归一化直方图: 计算每个灰度级别的概率分布。
3)遍历所有可能的阈值: 对于每一个灰度级别,都将其视为分割阈值T,将图像分割为前景(灰度值大于T)和背景(灰度值小于等于T)两部分。
4)计算类间方差: 根据前景和背景的灰度值及其所占的比例,计算当前阈值T下的类间方差。
5)选择最佳阈值: 遍历结束后,选择类间方差最大的阈值T作为最佳分割阈值。

三、代码演示

前面已经把主要核心介绍完了,接下来就是如何把图片里面的手掌提取出来并识别为对应的手势。

double cont_s, convex_s;//手势轮廓面积,凸包面积
double area_k, arc_k;//面积比,弧长比
Mat frame, hsv, dst, morp, binary, imgbinary;
vector<vector<cv::Point>> contours, contour;
vector<double> area;


cv::Mat img = cv::imread("..\\Hand\\TestPic\\Paper_mask.jpg", cv::IMREAD_COLOR);

frame = img;

cv::namedWindow("轮廓", cv::WINDOW_NORMAL);

GaussianBlur(frame, frame, Size(5, 5), 0, 0);

dst = YCrCb_Otsu_detect(frame);//检测皮肤

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));

morphologyEx(dst, morp, MORPH_OPEN, kernel);

Canny(morp, binary, 50, 200);

vector<Vec4i> hierachy;

findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);// 提取最外层轮廓

area.clear();

for (int i = 0; i < contours.size(); ++i) {
	area.push_back(contourArea(contours[i]));
}

int maxPosition = max_element(area.begin(), area.end()) - area.begin();//求面积最大的轮廓所在位置

vector<vector<cv::Point>> convex(1);
vector<vector<int>> intConvex(1);

cont_s = contourArea(contours[maxPosition]);

if (cont_s >= 400) 
{

	convexHull(contours[maxPosition], convex[0], false, false);//求手势的凸包轮廓(显示)
	convexHull(Mat(contours[maxPosition]), intConvex[0], false);//求手势的凸包轮廓(计算凸缺陷)

	drawContours(frame, convex, 0, cv::Scalar(0, 255, 0), 3);
	drawContours(frame, contours, maxPosition, cv::Scalar(255, 0, 0), 3);

	convex_s = contourArea(convex[0]);

	area_k = convex_s / cont_s;//计算面积比
	arc_k = arcLength(contours[maxPosition], true) / arcLength(convex[0], true);//计算周长比

	Rect rects = boundingRect(contours[maxPosition]);//获得包围手势轮廓的矩形

	RNG rngs = { 12345 };
	Scalar colors = Scalar(rngs.uniform(0, 255), rngs.uniform(0, 255), rngs.uniform(0, 255));
	rectangle(frame, rects, colors, 3);//画出包围手势轮廓的矩形

	vector<vector<cv::Vec4i>> defects(1);
	cv::convexityDefects(Mat(contours[maxPosition]), intConvex[0], defects[0]);

	int fNums = 0;
	//绘制凸缺陷
	for (int j = 0; j < defects[0].size(); j++) {
		cv::Vec4i& v = defects[0][j];
		float depth = v[3] / 256.0;
		if (depth > 350) {
			int startidx = v[0];
			Point start(contours[maxPosition][startidx]);
			int endidx = v[1];
			Point end(contours[maxPosition][endidx]);
			int faridx = v[2];
			Point far(contours[maxPosition][faridx]);
			line(frame, start, end, Scalar(0, 0, 255), 6);
			line(frame, start, far, Scalar(0, 255, 0), 6);
			line(frame, end, far, Scalar(0, 255, 0), 6);
			circle(frame, far, 6, Scalar(0, 0, 255), -1);

			fNums++;
		}
	}
	
	printf("凸缺陷数为:%d...\r\n", fNums);

	switch (fNums)
	{
	case 0: {
		printf("当前手势为:石头...\r\n");
	}break;
	case 1: {
		printf("当前手势为:剪刀...\r\n");
	}break;
	case 4: {
		printf("当前手势为:布...\r\n");
	}break;

	default:
		break;
	}
}

imshow("轮廓", frame);
cv::waitKey(0);
	
return 0;

在这里插入图片描述

可看到识别当前的手势为布。

四、总结

本文介绍了一个基于OpenCV的石头、剪刀、布手势识别系统。通过图像预处理、轮廓提取、凸包计算以及凸缺陷分析,我们未来将进一步优化算法,提高识别精度和鲁棒性,并探索更多手势识别技术的应用场景。

如果你喜欢我的文章就关注我吧!

标签:缺陷,20,进阶,frame,凸包,contours,识别,手势,cv
From: https://blog.csdn.net/weixin_39985355/article/details/143050852

相关文章

  • 文字识别接口应用场景解析-身份证识别、发票识别API、车牌识别
    在快节奏的工作与生活环境中,如何提高企业工作效率、提升用户体验成为了人们追求的共同目标。针对市场发展需求,一种将任意场景图片中的文字转换为可编辑文本的文字识别技术出现在大众视野。翔云人工智能开放平台通过不断的技术创新,基于深度学习算法与自主ocr核心技术,提供了......
  • 2024-2025-1 20241401 《计算机基础与程序设计》 第五周学习总结
    班级链接2024计算机基础与程序设计作业要求第五周作业作业目标①Pep/9虚拟机②机器语言与汇编语言③算法与伪代码④测试:黑盒,白盒教材学习内容总结《计算机科学概论》第六章计算机操作:介绍了计算机的基本操作,包括机器语言的基本概念。机器语言是由一系......
  • 20222327 2024-2025-1 《网络与系统攻防技术》实验三实验报告
    一、实验内容1.正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或技巧2.通过组合应用各种技术实现恶意代码免杀3.用另一电脑实测,在杀软开启的情况下,可运行并回连成功,注明电脑的杀软名称与版本4.问题回答(1)杀软是如何检测出恶意代码的?基于特征码检测:杀毒软件中......
  • PFCL201C枕块式张力计ABB瑞士
    PFCL201C的测量范围涵盖了5kN至50kN的力值区间。这一宽广的测量范围使其能够在多种工业环境中胜任不同规模的张力测量任务。例如:轻载应用:5kN的下限足以应对许多精细材料的张力测量需求。重载应用:50kN的上限则足以应对大型板材或重型卷材的张力监测。更值得关注的是,PF......
  • 20222317 2024-2025-1 《网络与系统攻防技术》实验三实验报告
    一、实验内容本次实验目的为通过多次加密、文件格式欺骗、填充、加壳等技术手段实现恶意代码免杀,产生恶意程序,并尝试通过杀毒软件,不被杀毒软件检测出来。具体实验内容如下:1.正确使用msf编码器,使用msfvenom生成如jar之类的其他文件;2.能够使用veil,加壳工具;3.能够使用C+shellcode......
  • 2024.10.24 1234版
    起于《海奥华预言》的思考◆地球管理结构和参考持续更新中...... 英文地址:https://github.com/zhuyongzhe/Earth/tags中文地址:https://www.cnblogs.com/zhuyongzhe85作者:朱永哲 ---------------------------------------------------------------------------------......
  • 2024年韩顺平老师Python教程保姆级笔记
    代码获取:https://github.com/qingxuly/hsp_python_coursePython语言描述Python转义字符Python常用的转义字符转义字符说明\t制表符,实现对齐的功能\n换行符,\\一个\\"一个"\'一个'\r一个回车代码演示#\t制表符print("jack\t20")​#\n换行print("Hello,jack......
  • LevOJ P2084奇迹树脂
    题目概述:给定了函数f的表达式与函数g的表达式,给了T(T<=100)次询问,每次询问一个数n(n<=1e12),求g(n)的值,最终答案对1e9+7取模。tag:记忆化,递归,数学题解:首先我们需要知道取模的常识:1.(a+b)%mod=(a%mod+b%mod)%mod2.a*b%mod=a%mod*b%mod3.(a+b)%mod=(a+b+mod)%mod......
  • 烟火检测视频分析网关算法定制烟火识别技术在沿街商铺消防安全管理中的应用
    在沿街商铺的消防安全管理中,烟火检测视频分析网关算法的应用显得尤为重要。随着城市化进程的加快,沿街商铺数量激增,这些商铺在为居民生活带来便利的同时,也因店主安全意识不足、消防管理松散等问题,成为火灾隐患的高发区。因此,采用智能化的烟火识别技术,对于提升消防安全管理水平、预......
  • 华为OD机试真题-比赛-2024年OD统一考试(E卷)
    最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客     每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。题目描述一个有N个选手参加比......