先给出一个基础代码,等会慢慢讲解
这里用的语言是python,后面也是一直用python,因为这种语言在人工智能领域正在被广泛地使用,同时因为其容易上手并且数据库强大而受到欢迎。这里的编程平台你可以使用jupyter或者终端、pycharm都是可以的,只要提前下载好这些函数库就可以
import cv2
import mediapipe as mp
import time
cap = cv2.VideoCapture(1)
mpHands = mp.solutions.hands
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils
pTime = 0
cTime = 0
while True:
success, img = cap.read()
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = hands.process(imgRGB)
# print(results.multi_hand_landmarks)
if results.multi_hand_landmarks:
for handLms in results.multi_hand_landmarks:
for id, lm in enumerate(handLms.landmark):
# print(id, lm)
h, w, c = img.shape
cx, cy = int(lm.x * w), int(lm.y * h)
print(id, cx, cy)
# if id == 4:
cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,
(255, 0, 255), 3)
cv2.imshow("Image", img)
cv2.waitKey(1)
详细讲解
import cv2
import mediapipe as mp
import time
这三句话,首先毫无疑问我要引入库,cv2是机器视觉最常用的库之一,这里手势识别模型是mediapipe。这是一个准确概率极高的函数库,如果想要自己创立一个库也可以,还需要翻前面的博客学习机器学习方面,如何训练模型。第三个是时间,我们要计算英文叫frame rate的时间点,我不知道中文他叫什么。
cap = cv2.VideoCapture(0)
接下来需要引入视频流,这里是使用了自带函数,可以接入摄像头,数字0是自带摄像头,其他数字或者双引号括起来是自定义摄像头。
while True:
success, img = cap.read()
cv2.imshow("Image", img)
cv2.waitKey(1)
接下来我们构建一个循环,不断把摄像头读取的矩阵,注意:机器视觉从来都不是处理图片本身,而是根据一定原理转化为数字矩阵交给计算机计算。后面两句是打开一个窗口展示我们读取的画面。到这里已经可以在电脑上显示摄像画面。
mpHands = mp.solutions.hands
hands = mpHands.Hands()
首先第一个是我们在调用机器学习好的模型,那么第二个是我们需要配置一下这个模型的参数,这里参数一个有四个,需要下载点开库来看,分别是一个flag判断,一个你的手数量和当你追踪到手时最低概率多少可以成立这些参数等。这里写false就行,但是因为函数本身就是默认false,所以什么都不写。
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
接下来我们需要把原来的图像处理成为RGB图像,一般视觉中很少直接使用原图,都是处理成其他图像,这里RGB图像基础感兴趣可以百度下。如何把RGB图像传递给我们的函数
results = hands.process(imgRGB)
在这里你可以试着打一下结果
print(results.multi_hand_landmarks)
这里的结果是算法处理后,直接打印出了手的26个坐标的三个轴
if results.multi_hand_landmarks:
results.multi_hand_landmarks这里这个返回结果,如果检测到了就会返回1,所以才会用if 1:
mpDraw = mp.solutions.drawing_utils
我们想要画出这些点,并且这些21点需要联系,这需要顶尖的数学计算关系,这里不详细有兴趣的朋友可以看下,然后我们可以遍历这些关键点
for handLms in results.multi_hand_landmarks:
mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
这个时候就可以画出所有节点和连线
接下来我们要计算下FPS,fps指的是画面每秒传输帧数,即视频的画面数。视频每秒的帧数越高,画面越清晰,人物动作越流畅。
初始化
pTime = 0
cTime = 0
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
如何根据这个计算出来,我们把这个显示在屏幕上
cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
(255, 0, 255)这个是颜色,最后一个3是大小,(10, 70)是显示的位置
我们接下里又实用一个循环获取每个节点的编号和他的坐标
for id, lm in enumerate(handLms.landmark):
# print(id, lm)
h, w, c = img.shape
cx, cy = int(lm.x w), int(lm.y h)
print(id, cx, cy)
第一句提取下图片通道,第二句提取下节点坐标,打印一下
如果你想要特殊关注某个点,比如说拇指头或者小拇指都可以特别标注成其他颜色
if id == 4:
cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
至此简单的一个手势基础就已经完成了