亚博microros小车-原生ubuntu支持系列:6-整体检测
前面迁移了手部检测:亚博microros小车-原生ubuntu支持系列:4-手部检测-CSDN博客
亚博microros小车-原生ubuntu支持系列:5-姿态检测-CSDN博客
本篇迁移整体检测。
结合前两节的内容,本节例程实现即可检测手掌也可检测人体的功能。
背景知识:
概述
MediaPipe Holistic 是一个综合性的解决方案,能够同时检测和追踪面部、手部和人体的姿态。它结合了 MediaPipe 的 Face Mesh、Hands 和 Pose 模块,提供一个全面的多模态识别系统。
功能
· 面部网格:检测和追踪面部的 468 个关键点,用于细致的面部特征分析。
· 手部关键点:检测每只手的 21 个关键点,用于手势识别和跟踪。
· 人体姿态:检测人体的 33 个关键点,用于姿态估计。
· 多模态结合:同时处理和结合面部、手部和姿态的数据,提供更丰富的信息。
再用小车摄像头之前,先用笔记本电脑跑一下效果
import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_holistic = mp.solutions.holistic
lmDrawSpec = mp.solutions.drawing_utils.DrawingSpec(
color=(0, 0, 255), thickness=-1, circle_radius=3)
drawSpec = mp.solutions.drawing_utils.DrawingSpec(
color=(0, 255, 0), thickness=2, circle_radius=2)
holistic = mp_holistic.Holistic(
min_detection_confidence=0.5,# 设置最小检测置信度
min_tracking_confidence=0.5)# 设置最小跟踪置信度
cap = cv2.VideoCapture(0)#打开默认摄像头
while True:
ret,frame = cap.read()#读取一帧图像
#图像格式转换
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 因为摄像头是镜像的,所以将摄像头水平翻转
# 不是镜像的可以不翻转
frame= cv2.flip(frame,1)
#输出结果
results = holistic.process(frame)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
if results.face_landmarks:#绘制面部地标
mp_drawing.draw_landmarks(frame, results.face_landmarks,mp_holistic.FACEMESH_CONTOURS, lmDrawSpec,drawSpec)
if results.pose_landmarks:#绘制姿势地标
#print(f'pose_landmarks:{results.pose_landmarks}' )
# 关键点可视化
mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS, lmDrawSpec,drawSpec)
if results.left_hand_landmarks:#手部
mp_drawing.draw_landmarks(frame, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
if results.right_hand_landmarks:
mp_drawing.draw_landmarks(frame, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
cv2.imshow('MediaPipe pose', frame)
if cv2.waitKey(1) & 0xFF == 27:
break
cap.release()
整体检测
src/yahboom_esp32_mediapipe/yahboom_esp32_mediapipe/目录下新建文件03_Holistic.py
代码如下:
#!/usr/bin/env python3
# encoding: utf-8
#import ros lib
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Point
import mediapipe as mp
#import define msg
from yahboomcar_msgs.msg import PointArray
from cv_bridge import CvBridge
from sensor_msgs.msg import Image, CompressedImage
#import commom lib
import cv2 as cv
import numpy as np
import time
from rclpy.time import Time
import datetime
print("import done")
class Holistic(Node):
def __init__(self, name,staticMode=False, landmarks=True, detectionCon=0.5, trackingCon=0.5):
super().__init__(name)
self.mpHolistic = mp.solutions.holistic
self.mpFaceMesh = mp.solutions.face_mesh
self.mpHands = mp.solutions.hands
self.mpPose = mp.solutions.pose
self.mpDraw = mp.solutions.drawing_utils
#初始化模型
self.mpholistic = self.mpHolistic.Holistic(
static_image_mode=staticMode,
smooth_landmarks=landmarks,
min_detection_confidence=detectionCon,
min_tracking_confidence=trackingCon)
self.pub_point = self.create_publisher(PointArray,'/mediapipe/points',1000)
#关键点样式
self.lmDrawSpec = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 255), thickness=-1, circle_radius=3)
self.drawSpec = mp.solutions.drawing_utils.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2)
def findHolistic(self, frame, draw=True):
pointArray = PointArray()
img = np.zeros(frame.shape, np.uint8)
#格式转换
img_RGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
#使用模型检测
self.results = self.mpholistic.process(img_RGB)
if self.results.face_landmarks:#脸部信息
if draw: self.mpDraw.draw_landmarks(frame, self.results.face_landmarks, self.mpFaceMesh.FACEMESH_CONTOURS, self.lmDrawSpec, self.drawSpec)
self.mpDraw.draw_landmarks(img, self.results.face_landmarks, self.mpFaceMesh.FACEMESH_CONTOURS, self.lmDrawSpec, self.drawSpec)
for id, lm in enumerate(self.results.face_landmarks.landmark):
point = Point()
point.x, point.y, point.z = lm.x, lm.y, lm.z
pointArray.points.append(point)
if self.results.pose_landmarks:#位姿信息
if draw: self.mpDraw.draw_landmarks(frame, self.results.pose_landmarks, self.mpPose.POSE_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
self.mpDraw.draw_landmarks(img, self.results.pose_landmarks, self.mpPose.POSE_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
for id, lm in enumerate(self.results.pose_landmarks.landmark):
point = Point()
point.x, point.y, point.z = lm.x, lm.y, lm.z
pointArray.points.append(point)
if self.results.left_hand_landmarks:#手部
if draw: self.mpDraw.draw_landmarks(frame, self.results.left_hand_landmarks, self.mpHands.HAND_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
self.mpDraw.draw_landmarks(img, self.results.left_hand_landmarks, self.mpHands.HAND_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
for id, lm in enumerate(self.results.left_hand_landmarks.landmark):
point = Point()
point.x, point.y, point.z = lm.x, lm.y, lm.z
pointArray.points.append(point)
if self.results.right_hand_landmarks:
if draw: self.mpDraw.draw_landmarks(frame, self.results.right_hand_landmarks, self.mpHands.HAND_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
self.mpDraw.draw_landmarks(img, self.results.right_hand_landmarks, self.mpHands.HAND_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
for id, lm in enumerate(self.results.right_hand_landmarks.landmark):
point = Point()
point.x, point.y, point.z = lm.x, lm.y, lm.z
pointArray.points.append(point)
self.pub_point.publish(pointArray)
return frame, img
def frame_combine(slef,frame, src):
if len(frame.shape) == 3:
frameH, frameW = frame.shape[:2]
srcH, srcW = src.shape[:2]
dst = np.zeros((max(frameH, srcH), frameW + srcW, 3), np.uint8)
dst[:, :frameW] = frame[:, :]
dst[:, frameW:] = src[:, :]
else:
src = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
frameH, frameW = frame.shape[:2]
imgH, imgW = src.shape[:2]
dst = np.zeros((frameH, frameW + imgW), np.uint8)
dst[:, :frameW] = frame[:, :]
dst[:, frameW:] = src[:, :]
return dst
class MY_Picture(Node):
def __init__(self, name):
super().__init__(name)
self.bridge = CvBridge()
self.sub_img = self.create_subscription(
CompressedImage, '/espRos/esp32camera', self.handleTopic, 1) #获取esp32传来的图像
self.last_stamp = None
self.new_seconds = 0
self.fps_seconds = 1
self.holistic = Holistic('holistic')
#回调函数
def handleTopic(self, msg):
self.last_stamp = msg.header.stamp
if self.last_stamp:
total_secs = Time(nanoseconds=self.last_stamp.nanosec, seconds=self.last_stamp.sec).nanoseconds
delta = datetime.timedelta(seconds=total_secs * 1e-9)
seconds = delta.total_seconds()*100
if self.new_seconds != 0:
self.fps_seconds = seconds - self.new_seconds
self.new_seconds = seconds#保留这次的值
start = time.time()
frame = self.bridge.compressed_imgmsg_to_cv2(msg)
frame = cv.resize(frame, (640, 480))
cv.waitKey(10)
frame, img = self.holistic.findHolistic(frame,draw=False)
end = time.time()
fps = 1 / ((end - start)+self.fps_seconds)
text = "FPS : " + str(int(fps))
cv.putText(frame, text, (20, 30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)
dist = self.holistic.frame_combine(frame, img)
cv.imshow('dist', dist)
# print(frame)
cv.waitKey(10)
def main():
print("start it")
rclpy.init()
esp_img = MY_Picture("My_Picture")
try:
rclpy.spin(esp_img)
except KeyboardInterrupt:
pass
finally:
esp_img.destroy_node()
rclpy.shutdown()
视频播放,效果有些卡顿。