手部追踪技术与应用

在计算机视觉领域,手部追踪技术是一项重要的应用。通过结合OpenCV和MediaPipe库,可以构建出许多实时工作的应用程序,主要用于图像和视频处理。OpenCV是一个开源的计算机视觉和机器学习软件库,它提供了多种编程接口,用于图像和视频分析。MediaPipe则是一个用于构建音频、视频或任何时间序列数据的框架,它可以帮助构建各种媒体处理功能的管道。

MediaPipe的一些主要应用包括多手追踪、面部检测、目标检测与追踪、3D目标检测与追踪(Objectron)、自动视频裁剪管道(AutoFlip)等。MediaPipe使用单次手掌检测模型,一旦检测到手掌,就会在检测到的手掌区域执行精确的关键点定位,定位21个3D手掌坐标。MediaPipe管道利用多个模型,例如手掌检测模型,该模型从完整图像中返回定向的手边界框。裁剪后的图像区域被送入由手掌检测器定义的手部地标模型,并返回高保真度的3D手部关键点。

接下来,将实现手部追踪模型。首先,安装所需的模块:

pip install opencv-python pip install mediapipe

然后,检查网络摄像头的工作情况。以下是一个简单的代码示例,用于检测网络摄像头是否连接到计算机,并在输出窗口的左上角显示每秒帧数(fps)。

import cv2 import time cap = cv2.VideoCapture(0) pTime = 0 while True: > success, img = cap.read() > imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) > cTime = time.time() > fps = 1 / (cTime - pTime) > pTime = cTime > cv2.putText(img, f'FPS:{int(fps)}', (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) > cv2.imshow("Test", img) cv2.waitKey(1)

现在,让开始实现。导入所需的模块并初始化所需的变量。

import cv2 import mediapipe as mp import time cap = cv2.VideoCapture(0) mpHands = mp.solutions.hands hands = mpHands.Hands(static_image_mode=False, max_num_hands=2, min_detection_confidence=0.5, min_tracking_confidence=0.5) mpDraw = mp.solutions.drawing_utils pTime = 0 cTime = 0

在上述代码中,声明了一个名为“hands”的对象,用于检测手部,在默认情况下,如果查看“Hands()”类,将检测到手的数量设置为2,最小检测置信度设置为0.5,最小跟踪置信度设置为0.5。将使用“mpDraw”来绘制关键点。

现在,让编写一个while循环来执行代码。

while True: > success, img = cap.read() > imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) > results = hands.process(imgRGB) > if results.multi_hand_landmarks: > for handLms in results.multi_hand_landmarks: > for id, lm in enumerate(handLms.landmark): > h, w, c = img.shape > cx, cy = int(lm.x * w), int(lm.y * h) > cv2.circle(img, (cx, cy), 3, (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)

在上述代码中,从网络摄像头读取帧,并将图像转换为RGB。然后使用“hands.process()”函数在帧中检测手部。一旦手部被检测到,将定位关键点,然后使用cv2.circle突出显示关键点,并使用mpDraw.draw_landmarks连接关键点。

以下是完整的代码:

import cv2 import mediapipe as mp import time cap = cv2.VideoCapture(0) mpHands = mp.solutions.hands hands = mpHands.Hands(static_image_mode=False, max_num_hands=2, min_detection_confidence=0.5, min_tracking_confidence=0.5) 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) > if results.multi_hand_landmarks: > for handLms in results.multi_hand_landmarks: > for id, lm in enumerate(handLms.landmark): > h, w, c = img.shape > cx, cy = int(lm.x * w), int(lm.y * h) > cv2.circle(img, (cx, cy), 3, (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)

输出将是:

手部追踪模型输出

现在,让创建一个手部追踪模块,以便可以在其他项目中使用它。创建一个新的Python文件,首先让创建一个名为handDetector的类,其中包含两个成员函数,分别命名为findHands和findPosition。函数findHands将接受一个RGB图像,并在帧中检测手部并定位关键点并绘制地标,函数findPosition将提供手部的位置和ID。然后是主函数,其中初始化模块,并编写一个while循环来运行模型。在这里,可以将此设置或模块导入到任何其他相关项目中。

import cv2 import mediapipe as mp import time class handDetector(): def __init__(self, mode = False, maxHands = 2, detectionCon = 0.5, trackCon = 0.5): self.mode = mode self.maxHands = maxHands self.detectionCon = detectionCon self.trackCon = trackCon self.mpHands = mp.solutions.hands self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.detectionCon, self.trackCon) self.mpDraw = mp.solutions.drawing_utils def findHands(self,img, draw = True): imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) self.results = self.hands.process(imgRGB) if self.results.multi_hand_landmarks: for handLms in self.results.multi_hand_landmarks: if draw: self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS) return img def findPosition(self, img, handNo = 0, draw = True): lmlist = [] if self.results.multi_hand_landmarks: myHand = self.results.multi_hand_landmarks[handNo] for id, lm in enumerate(myHand.landmark): h, w, c = img.shape cx, cy = int(lm.x * w), int(lm.y * h) lmlist.append([id, cx, cy]) if draw: cv2.circle(img, (cx, cy), 3, (255, 0, 255), cv2.FILLED) return lmlist def main(): pTime = 0 cTime = 0 cap = cv2.VideoCapture(0) detector = handDetector() while True: success, img = cap.read() img = detector.findHands(img) lmlist = detector.findPosition(img) if len(lmlist) != 0: print(lmlist[4]) 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) if __name__ == "__main__": main()

输出将与上面所示相同,并跟踪手部的位置。完整的代码也可以在以下位置找到:

参考:

LinkedIn:感谢关注。

博客大赛

手部追踪

OpenCV

S

Syed Abdul Gaffar

热衷于挑战的刺激,解决复杂问题,并打造创新的AI解决方案,为社会带来改变。无论是优化还是构建可持续的AI生态系统,相信利用AI的力量为更大的利益服务。让集思广益,合作,一次改变世界,一次一个字节。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485