ROS集成Bebop Parrot无人机人脸跟随:如何仅识别单一人脸
解决Bebop无人机仅跟随特定人脸的问题
我之前做过类似的Parrot Bebop无人机人脸跟随项目,刚好能帮到你!当前代码用haarcascade_frontalface_default.xml只能检测所有正面人脸,没法区分你和其他人。要实现仅跟随自己的脸,我们需要在检测基础上加上人脸身份识别或者初始目标选择的逻辑,下面给你两个可行的方案:
方案一:快速实现——手动选择初始目标人脸
这个方法适合快速测试,不需要提前训练模型:
- 程序启动后,第一帧检测到人脸时,你可以通过点击屏幕选择自己的脸
- 记录这个目标人脸的颜色特征(比如直方图)
- 后续每一帧检测人脸时,计算新人脸和目标人脸的相似度,选择最匹配的那个作为跟随目标
代码示例(基于你的现有代码扩展)
import cv2 import numpy as np face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') target_face_hist = None # 存储目标人脸的颜色直方图,用于匹配 def select_target_face(frame, faces): # 绘制所有检测到的人脸框,让用户选择 for (x,y,w,h) in faces: cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2) cv2.imshow('Select Your Face', frame) print("点击你的脸来设置跟踪目标...") # 处理鼠标点击事件 def click_event(event, x, y, flags, param): global target_face_hist if event == cv2.EVENT_LBUTTONDOWN: for (fx, fy, fw, fh) in faces: if fx < x < fx+fw and fy < y < fy+fh: # 提取目标人脸的HSV直方图 face_roi = frame[fy:fy+fh, fx:fx+fw] hsv_face = cv2.cvtColor(face_roi, cv2.COLOR_BGR2HSV) target_face_hist = cv2.calcHist([hsv_face], [0,1], None, [180,256], [0,180,0,256]) cv2.normalize(target_face_hist, target_face_hist, 0, 255, cv2.NORM_MINMAX) print("目标人脸已选定!") cv2.destroyWindow('Select Your Face') cv2.setMouseCallback('Select Your Face', click_event) cv2.waitKey(0) def match_face(frame, faces): global target_face_hist best_match_score = 0 best_face = None for (x,y,w,h) in faces: # 计算当前人脸的直方图并和目标对比 face_roi = frame[y:y+h, x:x+w] hsv_face = cv2.cvtColor(face_roi, cv2.COLOR_BGR2HSV) hist = cv2.calcHist([hsv_face], [0,1], None, [180,256], [0,180,0,256]) cv2.normalize(hist, hist, 0, 255, cv2.NORM_MINMAX) score = cv2.compareHist(target_face_hist, hist, cv2.HISTCMP_CORREL) if score > best_match_score: best_match_score = score best_face = (x,y,w,h) return best_face # 主循环(替换cap为无人机的视频流) cap = cv2.VideoCapture(0) first_run = True while True: ret, frame = cap.read() if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) # 第一次检测到人脸时,让用户选择目标 if first_run and len(faces) > 0: select_target_face(frame, faces) first_run = False # 匹配目标人脸并绘制框 if target_face_hist is not None and len(faces) > 0: target_face = match_face(frame, faces) if target_face is not None: x,y,w,h = target_face cv2.rectangle(frame, (x,y), (x+w,y+h), (255,0,0), 2) # 在这里添加ROS控制逻辑:根据人脸中心和画面中心的偏移,发送Twist指令给Bebop cv2.imshow('Face Tracking', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
方案二:更稳定——训练自定义人脸识别模型
如果需要应对光线变化、角度变化等复杂场景,建议训练自己的人脸模型:
- 收集20-50张不同角度、光照下的自己的人脸照片,放在单独文件夹
- 用OpenCV的LBPH人脸识别器训练模型
- 检测人脸后,对每个人脸进行识别,只处理匹配度达标的人脸
关键代码片段
# 训练模型部分 import os import numpy as np from PIL import Image recognizer = cv2.face.LBPHFaceRecognizer_create() detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') def get_training_data(path): image_paths = [os.path.join(path, f) for f in os.listdir(path)] face_samples = [] ids = [] # 假设你的照片命名格式为:user.1.xxx.jpg(1是你的ID) for image_path in image_paths: img = Image.open(image_path).convert('L') img_np = np.array(img, 'uint8') id = int(os.path.split(image_path)[-1].split(".")[1]) faces = detector.detectMultiScale(img_np) for (x,y,w,h) in faces: face_samples.append(img_np[y:y+h,x:x+w]) ids.append(id) return face_samples, ids # 训练并保存模型 faces, ids = get_training_data('your_face_dataset') recognizer.train(faces, np.array(ids)) recognizer.save('trainer.yml') # 识别部分 recognizer.read('trainer.yml') for (x,y,w,h) in faces: gray_face = gray[y:y+h, x:x+w] id, confidence = recognizer.predict(gray_face) # 置信度越低,匹配度越高,阈值可调整 if confidence < 70: # 这是你的脸,执行跟随逻辑 cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)
结合ROS和Bebop的注意点
- 识别到目标人脸后,计算人脸中心与画面中心的偏移量,转换为
geometry_msgs/Twist类型的速度指令 - 使用
bebop_autonomy包发送控制消息时,记得添加平滑逻辑,避免无人机动作过于突兀
内容的提问来源于stack exchange,提问作者PedroSG
相关产品推荐
相关产品推荐

