本篇文章只是手势识别的一个demo,想要识别的精度更高,还需要添加其他的约束条件,这里只是根据每个手指关键点和手掌根部的距离来判断手指是伸展开还是弯曲的。关于mediapi pe的简介,可以去看官网:Home - mediapipe,官网有现成的demo程序,直接拷贝应用就可以实现手掌21个关键点的识别,这21个关键点的分布如下:
而且,检测的实时性也非常的不错:
当然,mediapipe不止可以检测手势,面部检测,姿态检测都可以:
下面说下这个手势识别的demo的大体思路:
首先,要import必要的库和导入必要的函数方法:
import cv2 as cv
import numpy as np
import mediapipe as mp
from numpy import linalg
#手部检测函数
mpHands = mp.solutions.hands
hands = mpHands.Hands()
#绘制关键点和连接线函数
mpDraw = mp.solutions.drawing_utils
handLmsStyle = mpDraw.DrawingSpec(color=(0, 0, 255), thickness=int(5))
handConStyle = mpDraw.DrawingSpec(color=(0, 255, 0), thickness=int(10))
其中,handLmsStyle和handConStyle分别是关键点和连接线的特征,包括颜色和关键点(连接线)的宽度。
如果画面中有手,就可以通过如下函数将关键点和连接线表示出来
if result.multi_hand_landmarks:
#同时出现两只手都可以检测
for i, handLms in enumerate(result.multi_hand_landmarks):
mpDraw.draw_landmarks(frame, handLms, mpHands.HAND_CONNECTIONS,
landmark_drawing_spec=handLmsStyle,
connection_drawing_spec=handConStyle)
有个这21个关键点,可以做的事情就太多了,比如控制电脑的音量,鼠标、键盘,如果有个完善的手势姿态库,还可以做比如手语识别等等。因为实际生活中,手的摆放不一定是正好手心面向摄像头的,所以约束条件越苛刻,精度就会越高,这里的做法就没有考虑这么多,就只是用手指不同姿态时的向量L2范数(就是向量的模,忘记了就看线性代数或者机器学习)不同,来粗略的检测,比如说食指,伸直的时候和弯曲的时候,指尖(点8)到手掌根部(点0)的向量模dist1肯定是大于点6到点0的向量模dist2的,如果食指弯曲的时候,则有dist1 < dist2,食指、中指、无名指和小拇指的判断都是如此,仅大拇指就点17代替的点0,代码如下:
for k in range (5):
if k == 0:
figure_ = finger_stretch_detect(landmark[17],landmark[4*k+2],
landmark[4*k+4])
else:
figure_ = finger_stretch_detect(landmark[0],landmark[4*k+2],
landmark[4*k+4])
然后通过五个手指的状态,来判断当前的手势,我这里列举了一些,简单粗暴:
def detect_hands_gesture(result):
if (result[0] == 1) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):
gesture = "good"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):
gesture = "one"
elif (result[0] == 0) and (result[1] == 0)and (result[2] == 1) and (result[3] == 0) and (result[4] == 0):
gesture = "please civilization in testing"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 1) and (result[3] == 0) and (result[4] == 0):
gesture = "two"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 1) and (result[3] == 1) and (result[4] == 0):
gesture = "three"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):
gesture = "four"
elif (result[0] == 1) and (result[1] == 1)and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):
gesture = "five"
elif (result[0] == 1) and (result[1] == 0)and (result[2] == 0) and (result[3] == 0) and (result[4] == 1):
gesture = "six"
elif (result[0] == 0) and (result[1] == 0)and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):
gesture = "OK"
elif(result[0] == 0) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):
gesture = "stone"
else:
gesture = "not in detect range..."
return gesture
然后根据判断的结果输出即可,效果如下:
完整代码如下:
import cv2 as cv
import numpy as np
import mediapipe as mp
from numpy import linalg
#视频设备号
DEVICE_NUM = 0
手指检测
point1-手掌0点位置,point2-手指尖点位置,point3手指根部点位置
def finger_stretch_detect(point1, point2, point3):
result = 0
#计算向量的L2范数
dist1 = np.linalg.norm((point2 - point1), ord=2)
dist2 = np.linalg.norm((point3 - point1), ord=2)
if dist2 > dist1:
result = 1
return result
检测手势
def detect_hands_gesture(result):
if (result[0] == 1) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):
gesture = "good"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):
gesture = "one"
elif (result[0] == 0) and (result[1] == 0)and (result[2] == 1) and (result[3] == 0) and (result[4] == 0):
gesture = "please civilization in testing"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 1) and (result[3] == 0) and (result[4] == 0):
gesture = "two"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 1) and (result[3] == 1) and (result[4] == 0):
gesture = "three"
elif (result[0] == 0) and (result[1] == 1)and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):
gesture = "four"
elif (result[0] == 1) and (result[1] == 1)and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):
gesture = "five"
elif (result[0] == 1) and (result[1] == 0)and (result[2] == 0) and (result[3] == 0) and (result[4] == 1):
gesture = "six"
elif (result[0] == 0) and (result[1] == 0)and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):
gesture = "OK"
elif(result[0] == 0) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):
gesture = "stone"
else:
gesture = "not in detect range..."
return gesture
def detect():
# 接入USB摄像头时,注意修改cap设备的编号
cap = cv.VideoCapture(DEVICE_NUM)
# 加载手部检测函数
mpHands = mp.solutions.hands
hands = mpHands.Hands()
# 加载绘制函数,并设置手部关键点和连接线的形状、颜色
mpDraw = mp.solutions.drawing_utils
handLmsStyle = mpDraw.DrawingSpec(color=(0, 0, 255), thickness=int(5))
handConStyle = mpDraw.DrawingSpec(color=(0, 255, 0), thickness=int(10))
figure = np.zeros(5)
landmark = np.empty((21, 2))
if not cap.isOpened():
print("Can not open camera.")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Can not receive frame (stream end?). Exiting...")
break
#mediaPipe的图像要求是RGB,所以此处需要转换图像的格式
frame_RGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
result = hands.process(frame_RGB)
#读取视频图像的高和宽
frame_height = frame.shape[0]
frame_width = frame.shape[1]
#print(result.multi_hand_landmarks)
#如果检测到手
if result.multi_hand_landmarks:
#为每个手绘制关键点和连接线
for i, handLms in enumerate(result.multi_hand_landmarks):
mpDraw.draw_landmarks(frame,
handLms,
mpHands.HAND_CONNECTIONS,
landmark_drawing_spec=handLmsStyle,
connection_drawing_spec=handConStyle)
for j, lm in enumerate(handLms.landmark):
xPos = int(lm.x * frame_width)
yPos = int(lm.y * frame_height)
landmark_ = [xPos, yPos]
landmark[j,:] = landmark_
# 通过判断手指尖与手指根部到0位置点的距离判断手指是否伸开(拇指检测到17点的距离)
for k in range (5):
if k == 0:
figure_ = finger_stretch_detect(landmark[17],landmark[4*k+2],landmark[4*k+4])
else:
figure_ = finger_stretch_detect(landmark[0],landmark[4*k+2],landmark[4*k+4])
figure[k] = figure_
print(figure,'\n')
gesture_result = detect_hands_gesture(figure)
cv.putText(frame, f"{gesture_result}", (30, 60*(i+1)), cv.FONT_HERSHEY_COMPLEX, 2, (255 ,255, 0), 5)
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
cap.release()
cv.destroyAllWindows()
if __name__ == '__main__':
detect()
我的公众号:
Original: https://blog.csdn.net/weixin_41747193/article/details/122117629
Author: 王三思
Title: opencv和mediapipe实现手势识别
相关阅读1
Title: ResNet+ FPN网络结构
1.ResNet
论文地址:ResNet
ResNet在PyTorch的官方代码中共有5种不同深度的结构分别为18、34、50、101、152,和论文的完全一致。如下图所示,下图是论文的截图。
根据Block类型,可以将这五种ResNet分为两类:一种是基于BasicBlock;另一种基于Bottleneck。
; 1.1 Block前面的层
如下图所示,
上图红色框的层的具体结构如下图所示,这里只包含卷积层和pooling层,而BN层和ReLU层等均未画出。
输入输出用椭圆形表示,中间是输入输出的尺寸:channel×height×width
这里补充一个卷积的基础知识(输出的宽公式如下图),O是代表输出尺寸,K 是过滤器尺寸,P 是填充,S 是步幅。
零填充:K 是过滤器尺寸,那么输入和输出内容就总能保持一致的空间维度。
1.2 BasicBlock
浅层网络ResNet18, 34都由BasicBlock搭成。下面就 ResNet18叙述一下BasicBlock。
conv2_x
conv2_x的结构比较简单,下图中方框内便是BasicBlock的主要结构——两个3×3 的卷积层,每个layer都由若干Block组成,又因为conv2_x的两个block结构完全相同,所以图中就x2代替。
conv3_x
conv2_x和conv3_x就有所不同了(如下图),首先64 _56_56(c,h,w)输入到第一个block的conv1中,这个conv1的步长变为2,和conv2_x不同,这是为了降低输入尺寸,减少数据量,输出尺寸为128 _28_28(c,h,w)。其次是将输入经过1 _1_128的kernel,步长为2,padding=1的卷积操作得到128 _28_28的输出(这里补充一个知识点,1x1 卷积作用:降维和升维,简单来说就是通道数的增加和减少)这个部分就是PyTorch ResNet代码中的downsample,然后和第一条路线合并,简单来说就是1x1的卷积步长是2。
到第二个block,由于已经降低了尺寸,第2个block的conv1的stride就设置为1。由于该block没有降低尺寸,residual和输出尺寸相同,所以也没有downsample部分。
conv4_x和conv5_x结构上与conv3_x相同,具体就输通道数的改变已经输出尺寸的缩小,就不具体赘述。
; 1.3 Bottleneck
Bottleneck,深层网络ResNet50, 101, 152乃至更深的网络,都由Bottleneck搭成。就 ResNet50叙述一下Bottleneck。
conv2_x
结构如下图所示,和Basicblock不同的一点是,每一个Bottleneck都会在输入和输出之间加上一个卷积层,只不过在layer1中还没有downsample,这点和Basicblock是相同的。至于一定要加上卷积层的原因,就在于Bottleneck的conv3会将输入的通道数扩展成原来的4倍,导致输入一定和输出尺寸不同。
conv3_x
conv3_x结构如下图所示,输出尺寸是256 _56_56,输入进入layer2的第1个block后,首先要通过conv1将通道数降下来,之后conv2负责将尺寸降低(stride=2,下图从左向右数第2个红圈标注)。到输出处,由于尺寸发生变化,需要将输入downsample,同样是通过stride=2的1×1卷积层实现。
之后的3个block(layer2有4个block)就不需要进行downsample了(无论是residual还是输入),如下图从左向右数第3、4个红圈标注,stride均为1。因为这3个block结构均相同,所以用x3表示。
conv4_x和conv5_x结构与conv3_x相同,就不赘述。
2.特征金字塔-Feature Pyramid Networks(FPN)
论文链接:RPN
2.1
目标检测任务和语义分割任务里面常常需要检测小目标。但是当小目标比较小时,可能在原
图里面只有几十个像素点。
对于深度卷积网络,从一个特征层卷积到另一个特征层,无论步长是1还是2还是更多,卷积核都要遍布整个图片进行卷积,大的目标所占的像素点比小目标多,所以大的目标被经过卷积核的次数远比小的目标多,所以在下一个特征层里,会学习到更多大目标的特点。
特别是在步长大于等于2的情况下,大目标的特点更容易得到保留,小目标的特征点容易被跳过。
因此,经过很多层的卷积之后,小目标的特点会越来越少。、
如上图,特征图(feature map)用蓝色轮廓表示,较粗的轮廓表示语义上更强的特征图。
- a. 使用图像金字塔构建特征金字塔。
特征是根据每个不同大小比例的图
像独立计算的,每计算一次特征都
需要resize一下图片大小,耗时,
速度很慢。 - b. 检测系统都在采用的为了更快地检
测而使用的单尺度特征检测。 - c. 由卷积计算的金字塔特征层次来进
行目标位置预测,但底层feature
map特征表达能力不足。 - d. 特征金字塔网络(FPN)和b,c一样快,
但更准确。
如下图,FPN的提出是为了实现更好的feature maps融合,一般的网络都是直接使用最后一层的feature maps,虽然最后一层的feature maps 语义强,但是位置和分辨率都比较低,容易检测不到比较小的物体。FPN的功能就是融合了底层到高层的feature maps ,从而充分的利用了提取到的各个阶段的特征(ResNet中的C2-C5)。
; 2.2特征金字塔FPN的构建(Mask R-CNN)
• 特征金字塔FPN的构建是为了实现特征多尺度的融合,在Mask R-CNN当中,我们取出在主干特征提取网络中长宽压缩了两次C2、三次C3、四次C4、五次C5的结果来进行特征金字塔结构的构造。
• P2-P5是将来用于预测物体的bbox,boxregression,mask的。
• P2-P6是用于训练RPN的,即P6只用于RPN网络中。
如下图所示(h,w,c)
FPN+Resnet
FPN+Resnet网络结构如下所示
参考:https://zhuanlan.zhihu.com/p/79378841
参考:https://zhuanlan.zhihu.com/p/103263215
Original: https://blog.csdn.net/weixin_43937959/article/details/122489181
Author: a little cabbage
Title: ResNet+ FPN网络结构
相关阅读2
Title: 图像增强库Albumentations使用总结
目录
Spatial-level transforms(空间层次转换)
ShiftScaleRotate 随机平移,缩放和旋转输入。
RandomGridShuffle把图像切成网格单元随机排列。
HueSaturationValue随机更改图像的颜色,饱和度和值。
GaussianBlur 使用随机核大小的高斯滤波器对图像进行模糊处理
ChannelShuffle随机重新排列输入RGB图像的通道。
摘要
albumentations 包是一种针对数据增强专门写的API ,里面基本包含大量的数据增强手段,其特点:
1 、Albumentations 支持所有常见的计算机视觉任务,如分类、语义分割、实例分割、目标检测和姿态估计。
2 、该库提供了一个简单统一的API ,用于处理所有数据类型:图像(rbg 图像、灰度图像、多光谱图像)、分割掩码、边界框和关键点。
3 、该库包含70 多种不同的增强功能,可以从现有数据中生成新的训练样本。
4 、Albumentations 快。我们对每个新版本进行基准测试,以确保增强功能提供最大的速度。
5 、它与流行的深度学习框架(如PyTorch 和TensorFlow)一起工作。顺便说一下,Albumentations 是PyTorch 生态系统的一部分。
6 、由专家写的。作者既有生产计算机视觉系统的工作经验,也有参与竞争性机器学习的经验。许多核心团队成员是Kaggle Masters 和Grandmasters 。
7 、该库广泛应用于工业、深度学习研究、机器学习竞赛和开源项目。
Albumentations 的 pip 安装
pip install albumentations
基准测试结果
测试使用ImageNet 验证集的前2000 张图像在Intel Xeon Gold 6140 CPU 运行基准测试的结果。所有输出都被转换为带有np 的连续NumPy 数组。uint8 数据类型。表格显示了在单个核上每秒可以处理的图像数量;高越好。
albumentations
0.5.0imgaug
0.4.0torchvision (Pillow-SIMD backend)
0.7.0keras
2.4.3augmentor
0.2.8solt
0.1.9HorizontalFlip
9909
2821226787323016223VerticalFlip
4374
22181952433919683562Rotate
371
2961632760345ShiftScaleRotate
635
43714728--Brightness
2751
11784192294182300Contrast
2756
1213352-3482305BrightnessContrast
2738
699195-1931179ShiftRGB
2757
1176-348--ShiftHSV
597
28458--137Gamma
2844
-382--946Grayscale
5159
428709-10641273RandomCrop64
175886
301852103-4177420732PadToSize512
3418
-574--2874Resize5121003634
1036
-1016977RandomSizedCrop_64_512
3191
9391594-15292563Posterize
2778
735
-Multiply
2727
1248----MultiplyElementwise118
209
Original: https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/116460996
Author: AI浩
Title: 图像增强库Albumentations使用总结
相关阅读3
Title: tensorflow和keras版本选择(截止2021-08-08)
如果没有提供--env选项,则默认使用tensorFlow -1.9镜像,该镜像和提前装好的Python 3.6、Keras 2.2.0和TensorFlow 1.9.0一起提供。
Framework
Env name (--env parameter)
环境参数
Description
Docker Image
dcoker镜像网址
Packages and Nvidia SettingsTensorFlow 2.2tensorflow-2.2TensorFlow 2.2.0 + Keras 2.3.1 on Python 3.7.
TensorFlow 2.1tensorflow-2.1TensorFlow 2.1.0 + Keras 2.3.1 on Python 3.6.
TensorFlow 2.0tensorflow-2.0TensorFlow 2.0.0 + Keras 2.3.1 on Python 3.6.
TensorFlow 1.15tensorflow-1.15TensorFlow 1.15.0 + Keras 2.3.1 on Python 3.6.
TensorFlow 1.14tensorflow-1.14TensorFlow 1.14.0 + Keras 2.2.5 on Python 3.6.
TensorFlow 1.13tensorflow-1.13TensorFlow 1.13.0 + Keras 2.2.4 on Python 3.6.
TensorFlow 1.12tensorflow-1.12TensorFlow 1.12.0 + Keras 2.2.4 on Python 3.6.
tensorflow-1.12:py2TensorFlow 1.12.0 + Keras 2.2.4 on Python 2.
TensorFlow 1.11tensorflow-1.11TensorFlow 1.11.0 + Keras 2.2.4 on Python 3.6.
tensorflow-1.11:py2TensorFlow 1.11.0 + Keras 2.2.4 on Python 2.
TensorFlow 1.10tensorflow-1.10TensorFlow 1.10.0 + Keras 2.2.0 on Python 3.6.
tensorflow-1.10:py2TensorFlow 1.10.0 + Keras 2.2.0 on Python 2.
TensorFlow 1.9tensorflow-1.9TensorFlow 1.9.0 + Keras 2.2.0 on Python 3.6.
tensorflow-1.9:py2TensorFlow 1.9.0 + Keras 2.2.0 on Python 2.
TensorFlow 1.8tensorflow-1.8TensorFlow 1.8.0 + Keras 2.1.6 on Python 3.6.
tensorflow-1.8:py2TensorFlow 1.8.0 + Keras 2.1.6 on Python 2.
TensorFlow 1.7tensorflow-1.7TensorFlow 1.7.0 + Keras 2.1.6 on Python 3.6.
tensorflow-1.7:py2TensorFlow 1.7.0 + Keras 2.1.6 on Python 2.
TensorFlow 1.5tensorflow-1.5TensorFlow 1.5.0 + Keras 2.1.6 on Python 3.6.
tensorflow-1.5:py2TensorFlow 1.5.0 + Keras 2.1.6 on Python 2.
TensorFlow 1.4tensorflow-1.4TensorFlow 1.4.0 + Keras 2.0.8 on Python 3.6.
tensorflow-1.4:py2TensorFlow 1.4.0 + Keras 2.0.8 on Python 2.
TensorFlow 1.3tensorflow-1.3TensorFlow 1.3.0 + Keras 2.0.6 on Python 3.6.
tensorflow-1.3:py2TensorFlow 1.3.0 + Keras 2.0.6 on Python 2.
TensorFlow 1.2tensorflow-1.2TensorFlow 1.2.0 + Keras 2.0.6 on Python 3.5.
tensorflow-1.2:py2TensorFlow 1.2.0 + Keras 2.0.6 on Python 2.
TensorFlow 1.1tensorflowTensorFlow 1.1.0 + Keras 2.0.6 on Python 3.5.
tensorflow:py2TensorFlow 1.1.0 + Keras 2.0.6 on Python 2.
TensorFlow 1.0tensorflow-1.0TensorFlow 1.0.0 + Keras 2.0.6 on Python 3.5.
tensorflow-1.0:py2TensorFlow 1.0.0 + Keras 2.0.6 on Python 2.
TensorFlow 0.12tensorflow-0.12TensorFlow 0.12.1 + Keras 1.2.2 on Python 3.5.
tensorflow-0.12:py2TensorFlow 0.12.1 + Keras 1.2.2 on Python 2.
PyTorch 1.5pytorch-1.5PyTorch 1.5.0 + fastai 1.0.61 on Python 3.7.
PyTorch 1.4pytorch-1.4PyTorch 1.4.0 + fastai 1.0.60 on Python 3.6.
PyTorch 1.3pytorch-1.3PyTorch 1.3.0 + fastai 1.0.60 on Python 3.6.
PyTorch 1.2pytorch-1.2PyTorch 1.2.0 + fastai 1.0.60 on Python 3.6.
PyTorch 1.1pytorch-1.1PyTorch 1.1.0 + fastai 1.0.57 on Python 3.6.
PyTorch 1.0pytorch-1.0PyTorch 1.0.0 + fastai 1.0.51 on Python 3.6.
pytorch-1.0:py2PyTorch 1.0.0 on Python 2.
PyTorch 0.4pytorch-0.4PyTorch 0.4.1 on Python 3.6.
pytorch-0.4:py2PyTorch 0.4.1 on Python 2.
PyTorch 0.3pytorch-0.3PyTorch 0.3.1 on Python 3.6.
pytorch-0.3:py2PyTorch 0.3.1 on Python 2.
PyTorch 0.2pytorch-0.2PyTorch 0.2.0 on Python 3.5
pytorch-0.2:py2PyTorch 0.2.0 on Python 2.
PyTorch 0.1pytorch-0.1PyTorch 0.1.12 on Python 3.
pytorch-0.1:py2PyTorch 0.1.12 on Python 2.
Theano 0.9theano-0.9Theano rel-0.8.2 + Keras 2.0.3 on Python3.5.
theano-0.9:py2Theano rel-0.8.2 + Keras 2.0.3 on Python2.
CaffecaffeCaffe rc4 on Python3.5.
caffe:py2Caffe rc4 on Python2.
TorchtorchTorch 7 with Python 3 env.
torch:py2Torch 7 with Python 2 env.
Chainer 1.23chainer-1.23Chainer 1.23.0 on Python 3.
chainer-1.23:py2Chainer 1.23.0 on Python 2.
Chainer 2.0chainer-2.0Chainer 1.23.0 on Python 3.
chainer-2.0:py2Chainer 1.23.0 on Python 2.
MxNet 1.0mxnetMxNet 1.0.0 on Python 3.6.
mxnet:py2MxNet 1.0.0 on Python 2.
说明:记录学习笔记,如果错误欢迎指正!转载请联系我。
Original: https://blog.csdn.net/csdn_xmj/article/details/119534425
Author: 双木的木
Title: tensorflow和keras版本选择(截止2021-08-08)