当前位置: 首页 > 编程日记 > 正文

基于 OpenCV 的手掌检测和手指计数

作者 | 努比

来源 | 小白学视觉

利用余弦定理使用OpenCV-Python实现手指计数与手掌检测。

176c4affd67f84346cf7d2827d5e2e30.png

手检测和手指计数

接下来让我们一起探索以下这个功能是如何实现的。

OpenCV

OpenCV(开源计算机视觉库)是一个开源计算机视觉和机器学习软件库。OpenCV的构建旨在为计算机视觉应用程序提供通用的基础结构,并加速在商业产品中使用机器感知。

导入库

• cv2: opencv [pip install opencv]

• numpy:用于处理数组和数学[pip install numpy]

import cv2 as cv
import numpy as np

导入图像

img_path = "data/palm.jpg"
img = cv.imread(img_path)
cv.imshow('palm image',img)

79f60a8018a6d539b169dccc66310f11.png

手掌图像

皮肤Mask

• 用于突出显示图像上的特定颜色。

• hsvim:将BGR(蓝色,绿色,红色)图像更改为HSV(色相,饱和度,值)。

• 较低:HSV中的肤色范围较小。

• upper:HSV中皮肤颜色的上限。

• skinRegionHSV:在HSV色彩空间的上下像素值范围内检测皮肤。

• 模糊:使图像模糊以改善遮罩。

• 脱粒:脱粒。

hsvim = cv.cvtColor(img, cv.COLOR_BGR2HSV)
lower = np.array([0, 48, 80], dtype = "uint8")
upper = np.array([20, 255, 255], dtype = "uint8")
skinRegionHSV = cv.inRange(hsvim, lower, upper)
blurred = cv.blur(skinRegionHSV, (2,2))
ret,thresh = cv.threshold(blurred,0,255,cv.THRESH_BINARY)
cv.imshow("thresh", thresh)

7b6e3484c2126367f80f7c20af3be61d.png

处理结果

轮廓线绘制

现在让我们在图像上找到轮廓。

contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
contours = max(contours, key=lambda x: cv.contourArea(x))
cv.drawContours(img, [contours], -1, (255,255,0), 2)
cv.imshow("contours", img)

4c965e8b4696764bc0cf6b4b56f9817b.png

手掌轮廓线

凸包检测

hull = cv.convexHull(contours)
cv.drawContours(img, [hull], -1, (0, 255, 255), 2)
cv.imshow("hull", img)

790351bf7464129c6c4fd62dcb1870fd.png

检测结果

凸缺陷检测

手掌与凸包检测轮廓线的任何偏离的地方都可以视为凸度缺陷。

hull = cv.convexHull(contours, returnPoints=False)
defects = cv.convexityDefects(contours, hull)

3aaa11f5debba18c0f6548afc417a8ba.png

凸缺陷示例

手指个数计算

凸缺陷返回一个数组,其中每一行都包含以下值:

• 起点

• 终点

• 最远点

• 到最远点的大概距离

通过这一点,我们可以轻松得出Sides:a,b,c(请参见CODE),并且根据余弦定理,我们还可以得出两根手指之间的伽马或角度。如前所述,如果伽玛小于90度,我们会将其视为手指。知道伽玛后,我们只需画一个半径为4的圆,到最远点的近似距离即可。在将文本简单地放入图像中之后,我们就表示手指数(cnt)。

if defects is not None:
cnt = 0
for i in range(defects.shape[0]): # calculate the angle
s, e, f, d = defects[i][0]
start = tuple(contours[s][0])
end = tuple(contours[e][0])
far = tuple(contours[f][0])
a = np.sqrt((end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2)
b = np.sqrt((far[0] - start[0]) ** 2 + (far[1] - start[1]) ** 2)
c = np.sqrt((end[0] - far[0]) ** 2 + (end[1] - far[1]) ** 2)
angle = np.arccos((b ** 2 + c ** 2 - a ** 2) / (2 * b * c)) # cosine theorem
if angle <= np.pi / 2: # angle less than 90 degree, treat as fingers
cnt += 1
cv.circle(img, far, 4, [0, 0, 255], -1)
if cnt > 0:
cnt = cnt+1
cv.putText(img, str(cnt), (0, 50), cv.FONT_HERSHEY_SIMPLEX,1, (255, 0, 0) , 2, cv.LINE_AA)

让我们看看最终结果

cv.imshow('final_result',img)

de1d806f39c8b989c57338d022cbc582.png

我们也可以通过调用“ cv.VideoCapture()”来对视频执行此操作。

代码链接如下:

https://github.com/madhav727/medium/blob/master/finger_counting_video.py

相关文章:

side menu待研究

2019独角兽企业重金招聘Python工程师标准>>> http://fontawesome.bootstrapcheatsheets.com/ http://www.queness.com/post/14666/recreate-google-nexus-menu http://www.jqueryscript.net/demo/Sliding-Side-Menu-Panel-with-jQuery-Bootstrap-BootSideMenu/ &a…

Gitlab Issue Tracker and Wiki(一)

本节内容&#xff1a;创建第一个问题创建第一个合并请求接受合并请求工作里程碑在提交中引用问题创建维基百科页使用Gollum管理维基百科一. 创建问题1. 登陆Gitlab服务器2. 切换到想要创建问题的项目3. 点击Issues.4. 点击【New issue】5. 根据情况进行填写。二. 创建合并请求1…

runtime实践之Method Swizzling

利用 Objective-C 的 Runtime 特性&#xff0c;我们可以给语言做扩展&#xff0c;帮助解决项目开发中的一些设计和技术问题。这一篇&#xff0c;我们来探索一些利用 Objective-C Runtime 的黑色技巧。这些技巧中最具争议的或许就是 Method Swizzling 。 介绍一个技巧&#xff0…

网络协议关系拓扑图 很全面 很好

NETWORK ASSOCIATES GUIDE TO COMMUNICATIONS PROTOCOLS 网络协议关系拓扑图 很全面 很好 值得收藏&#xff01;

一行代码搞定 Python 逐行内存消耗分析

作者 | 费弗里来源 | Python大数据分析我们即将学习的是&#xff1a;一行代码分析Python代码行级别内存消耗。很多情况下&#xff0c;我们需要对已经写好的Python程序的内存消耗进行优化&#xff0c;但是一段代码在运行过程中的内存消耗是动态变化的&#xff0c;这种时候就可以…

崛起于Springboot2.X之Mybatis-全注解方式操作Mysql(4)

为什么80%的码农都做不了架构师&#xff1f;>>> 1、使用注解方式对mysql增删改查,它很方便&#xff0c;不像一些逆向工程工具一样生成的都是乱七八糟&#xff0c;虽然很全的方法&#xff0c;完全手写sql 基于上一篇博客&#xff0c;我们只需要新建一个目录dao层&am…

hdu 1247

Problem DescriptionA hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.You are to find all the hat’s words in a dictionary.InputStandard input consists of a number of lowercase words, one per li…

php执行URL解析

方法一&#xff1a; $url"http://www.baidu.com";file_get_contents($url);方法二&#xff1a; // CURL 方法$url"http://www.baidu.com";$ch curl_init( );curl_setopt( $ch,CURLOPT_URL,$url );curl_setopt( $ch,CURLOPT_HEADER,0 );curl_setopt( $ch,…

Python 来分析,堪比“唐探系列”!B站9.5分好评如潮!

作者 | 菜鸟哥来源 | 菜鸟学PythonHello 小伙伴们&#xff0c;最近一部非常不错的悬疑侦探喜剧 电影&#xff0c;登上B站热榜&#xff01;菜鸟哥看完之后&#xff0c;大呼过瘾&#xff0c;简直就是一本非常棒的"剧本杀"&#xff01;演员都是实力派&#xff0c;演技超…

10进制转换为二十六进制字符串A-Z

def convert10to26(num): ...: 10进制转为26进制字母 A-Z, 输入参数10进制数num, 返回26位的字母A-Z 参数type&#xff1a; num: int return: str ...: ...: digit_list [] # 列表当栈使用&#xff0c;存储每次求余的结果 ...: while num !0: ...: digit_list.append(num%26)…

从hello world 说程序运行机制

http://www.cnblogs.com/yanlingyin/archive/2012/03/05/2379199.html 开篇 学习任何一门编程语言&#xff0c;都会从hello world 开始。对于一门从未接触过的语言&#xff0c;在短时间内我们都能用这种语言写出它的hello world。然而&#xff0c;对于hello world 这个简单程序…

爱耳日腾讯天籁行动再升级 助力100位青年听障人才打破“屏障”

公益是解决社会问题的重要切入口&#xff0c;科技是提升效率的强有力工具。当产业技术走入公益场景&#xff0c;科技也在发挥更大的社会价值。 《中国听力健康报告&#xff08;2021&#xff09;》显示&#xff0c;过度的噪音曝露&#xff0c;正让全球11亿年轻人面临听力受损的风…

IOS推送详解

为什么80%的码农都做不了架构师&#xff1f;>>> IOS推送详解 一.关于推送通知 推送通知&#xff0c;也被叫做远程通知&#xff0c;是在iOS 3.0以后被引入的功能。是当程序没有启动或不在前台运行时&#xff0c;告诉用户有新消息的一种途径&#xff0c;是从外部服务…

redis(4)

redis-cli -p 6380redis-cli -p 6379 info server | grep run_idpsync &#xff1f; -1

PHP也玩并发,巧用curl 并发减少后端访问时间

说明&#xff1a;本人源自3篇博文 http://blog.csdn.net/zuiaituantuan/article/details/7048782首先&#xff0c;先了解下 php中的curl多线程函数&#xff1a;# curl_multi_add_handle# curl_multi_close# curl_multi_exec# curl_multi_getcontent# curl_multi_info_read# cur…

ADSL自动更换IP地址源代码

有些网站限制IP地址&#xff0c;什么一个IP地址只能一次之类的。特别是投票网址&#xff0c;为了防止刷票&#xff0c;限制1个IP只允许投票一次&#xff01; 此程序采用Vs2010C#开发&#xff0c;提供全部源代码&#xff01;方便程序猿朋友二次开发&#xff01; 可以后台运行&am…

安全隐患:神经网络可以隐藏恶意软件

编译 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 凭借数百万和数十亿的数值参数&#xff0c;深度学习模型可以做到很多的事情&#xff0c;例如&#xff0c;检测照片中的对象、识别语音、生成文本以及隐藏恶意软件。加州大学圣地亚哥分校和伊利诺伊大学…

实现一个完美符合Promise/A+规范的Promise

原文在我的博客中&#xff1a;原文地址 如果文章对您有帮助&#xff0c;您的star是对我最好的鼓励&#xff5e; 简要介绍&#xff1a;Promise允许我们通过链式调用的方式来解决“回调地狱”的问题&#xff0c;特别是在异步过程中&#xff0c;通过Promise可以保证代码的整洁性和…

用递归法计算斐波那契数列的第n项

斐波纳契数列&#xff08;Fibonacci Sequence&#xff09;又称黄金分割数列&#xff0c;指的是这样一个数列&#xff1a;1、1、2、3、5、8、13、21、……在数学上&#xff0c;斐波纳契数列以如下被以递归的方法定义&#xff1a;F00&#xff0c;F11&#xff0c;FnF(n-1)F(n-2)&a…

ArrayList的内存泄露

2019独角兽企业重金招聘Python工程师标准>>> 大家先运行下下面这段代码&#xff0c;看看结果 public class MemoryLeak {public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {Overridepublic void run() {for (int i …

给 Python 初学者推荐的 IDE 哦!

作者 | 黄伟呢来源 | 数据分析与统计学之美总有一些Python初学者&#xff0c;会问到&#xff1a;学习Python&#xff0c;应该用什么Python IDE&#xff1f;了解到他们使用Python做什么之后&#xff0c;我总结了这篇文章。IDE是集成开发环境的缩写&#xff0c;通俗地说&#xff…

django 2.0路由配置变化

urlpatterns变量​​的语法 urlpatterns应该是path()和/或re_path()实例的Python列表。 首先&#xff0c;Django会使用根路由解析模块(root URLconf)来解析路由。 通常&#xff0c;这是ROOT_URLCONF设置的值&#xff0c;但是如果传入的HttpRequest对象具有urlconf属性&#xff…

用ext_skel,实现一个PHP扩展,添加到PHP并调用

http://www.shinrun.com/PHP 一、开始之前 1. 系统环境&#xff1a;FreeBSD 8.22. AP环境&#xff1a;即已经装好的Apache2.2.17、PHP5.3.8环境3. PHP源码&#xff1a;下载稳定版本源码到当前用户的目录&#xff0c;如&#xff0c;下载PHP 5.3.8到/usr/home/abc下。4. 其它要求…

关于第三方IOS的checkBox框架的使用

关于第三方IOS的checkBox框架的使用 这个框架是从github上下载获取的&#xff1a;M13Checkbox。 只是github的源码项目工程比较久远&#xff0c;所以我把代码部分拷贝到XCode 7.1.0新建的项目里。 下面是展示效果 客户端源码使用参考&#xff1a; 1 #import "ViewControll…

20 个 Pandas 数据实战案例,干货多多

作者 | 俊欣来源 | 关于数据分析与可视化今天我们讲一下pandas当中的数据过滤内容&#xff0c;小编之前也写过也一篇相类似的文章&#xff0c;但是是基于文本数据的过滤&#xff0c;大家有兴趣也可以去查阅一下。下面小编会给出大概20个案例来详细说明数据过滤的方法&#xff0…

Python创建和访问字典

>>> dict1 {a:1,b:2,c:3,d:4}>>> print(a的值是:,dict1[a])a的值是: 1>>> dict4 dict(我 快乐, 你 伤悲)SyntaxError: keyword cant be an expression>>> dict4[你] 改变悲伤>>> dict4{我: 快乐, 你: 改变悲伤}>>>…

C语言九阴真经

发现记忆力越来越差&#xff0c;所以干脆搞这么一个东西&#xff0c;就是把C语言的最常用的语法汇编在一起&#xff0c;不断完善。这样以后只要经常把这个回顾一下就可以了。不然去翻书太多了。。。f.h#define Area 1000 struct student{char *last_name;int student_id;char …

听障人士的“有声桥梁”:百度智能云曦灵-AI手语平台发布

在刚刚落幕的冰雪赛事中&#xff0c;百度智能云曦灵为央视新闻打造的AI手语主播正式上岗&#xff0c;她以流畅、专业的手语服务实时传递冰雪运动的激情。然而在日常生活中&#xff0c;听障人士想要方便地获取信息仍面临着众多困难&#xff0c;无障碍窗口稀缺的问题亟待解决。 …

模拟实现: strstr strcpy strlen strcat strcmp memcpy memmove

模拟实现&#xff1a;strstrstrcpystrlenstrcatstrcmpmemcpymemmove1 strstr 字符串中查找子字符串char * my_strstr(const char *dest, const char *src) {const char *ret dest;const char *p dest;const char *q src;assert(dest ! NULL && src ! NULL); while(r…

【Spring Security】五、自定义过滤器

在之前的几篇security教程中&#xff0c;资源和所对应的权限都是在xml中进行配置的&#xff0c;也就在http标签中配置intercept-url&#xff0c;试想要是配置的对象不多&#xff0c;那还好&#xff0c;但是平常实际开发中都往往是非常多的资源和权限对应&#xff0c;而且写在配…