基于大疆EP和Opencv完成人脸跟随项目
- 知识储备
- 实现步骤
- 环境安装
- 具体步骤
- 总体代码
知识储备
我们需要了解三方面的知识,第一方面是python的语法结构,也是最基础的,第二方面是opencv的基础知识,第三方面就是大疆的SDK啦,只有我们具备了这些知识,就可以简单完成人脸识别项目啦。
Opencv学习网站https://www.bilibili.com/video/BV1oJ411D71z 大疆EP的开发者文档网址https://robomaster-dev.readthedocs.io/zh_CN/latest/ 至于python的语法结构,大家可以到MOOC,哔哩哔哩等地方找资源哦,适合自己的才是最好的哦
实现步骤
连接EP——获取EP图像——处理EP图像——获得人脸坐标——控制云台运动
下面我们就开始吧。
环境安装
安装python请参考
在运行程序的时候我们需要在python安装robomaster库和opencv库
安装robomaster库 在电脑的cmd输入pip install robomaster
在使用SDK时候需要安装VC,不然会出现下面的错误
需要安装VC,下载地址https://github.com/dji-sdk/robomaster-sdk 安装opencv : pip install opencv-python
具体步骤
1.连接EP,在大疆的开发者文档里有
WiFi 直连
import robomaster
from robomaster import robot
if __name__ == '__main__':
# 如果本地IP 自动获取不正确,手动指定本地IP地址
# robomaster.config.LOCAL_IP_STR = "192.168.2.20"
ep_robot = robot.Robot()
# 指定连接方式为AP 直连模式
ep_robot.initialize(conn_type='ap')
version = ep_robot.get_version()
print("Robot version: {0}".format(version))
ep_robot.close()
其他连接方法请参考大疆的SDK开发文档
2.获取EP的视频流-该项目显示200帧的视频流
// An highlighted block
import time
import cv2
import robomaster
from robomaster import robot
if __name__ == '__main__':
ep_robot = robot.Robot()
ep_robot.initialize(conn_type="sta")
ep_camera = ep_robot.camera
# 显示200帧图传
ep_camera.start_video_stream(display=False)
for i in range(0, 200):
img = ep_camera.read_cv2_image()
cv2.imshow("Robot", img)
cv2.waitKey(1)
cv2.destroyAllWindows()
ep_camera.stop_video_stream()
ep_robot.close()
3.处理EP图像并获取人脸坐标
def shibei():
global RLzhongxi_x,RLzhongxi_y #定义两个全局变量,用来储存人脸的坐标
cv2.namedWindow("img", 1) #新建一个显示窗口
cv2.resizeWindow("img", 800, 400) #图像框的大小
ret,img=cap.read()#vc.read()读取图片的第一帧 返回两个值,第一个值是true或者false,判断有没有读取到,第二个值是当前的一帧图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#将读取到的值转化为灰度图
faces = face_cascade.detectMultiScale(gray,1.1,5)#检测出图片中所有的人脸,并将人脸的各个坐标保持到faces里
if len(faces)>0:#判断是否检测到人脸
for faceRect in faces: #依次读取faces的值
x,y,w,h = faceRect
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),3)#绘制人脸框
roi_gray = gray[y:y+h//2,x:x+w]
roi_color = img[y:y+h//2,x:x+w]
RLzhongxi_x = x+w/2 #获取人脸中心坐标
RLzhongxi_y = y+h/2
eyes = eye_cascade.detectMultiScale(roi_gray,1.1,1,cv2.CASCADE_SCALE_IMAGE,(2,2))#检测眼睛
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)#绘制眼睛框
cv2.imshow("img",img)#显示图像
return RLzhongxi_x,RLzhongxi_y#返回人脸中心坐标
4.控制云台运动
云台有两个轴,分别是航向轴和俯仰轴,航向轴是围绕的y轴转动,俯仰轴是围绕x轴转动,我们要做的是控制两个轴转到人脸的中心。
// An highlighted block
def Error():
RLzhongxi_x_1=centre[0]#将上面的值传到这里
RLzhongxi_y_1=centre[1]
TXzhongxi_x=400 #整个图像的中心坐标
TXzhongxi_y=200
error_x=TXzhongxi_x-RLzhongxi_x_1 #偏航轴的的误差
error_y=TXzhongxi_y-RLzhongxi_y_1#俯仰轴的误差
if abs(error_x) < 10:#判断误差是否小于10,如果小于默认为到达人脸中心
yaw0_speed = 0
else:
yaw0_speed = KP*error_x#输出偏航轴的速度
if abs(error_y) < 10:
pitch0_speed = 0
else:
pitch0_speed = -KP*error_y#输出俯仰轴的速度
print("yaw的速度:",yaw0_speed)
print("Pitch的速度:",pitch0_speed)
ep_gimbal.drive_speed(pitch_speed='{pitch}', yaw_speed='{yaw}'.format(pitch=pitch0_speed,yaw=yaw0_speed))#控制云台
总体代码
#导入需要用到的库
import cv2
import numpy as np
import wave
import re
import socket
import sys
import numpy as np
#创建新的对象
ep_robot = robot.Robot()
# 指定连接方式为AP 直连模式,初始化
ep_robot.initialize(conn_type='ap')
#开始获取视频流,但是不播放
ep_camera.start_video_stream(display=False)
#设置模式为自由模式
ep_robot.set_robot_mode(mode=robot.FREE)
#获取官方提供的特征库,根据自己电脑设置路径
face_cascade = cv2.CascadeClassifier("D://python38//Lib//site-packages//cv2//data//haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("D://python38//Lib//site-packages//cv2//data//haarcascade_eye.xml")
KP = 0.15#比例系数,让云台转的慢一点
def shibei():
global RLzhongxi_x,RLzhongxi_y #定义两个全局变量,用来储存人脸的坐标
cv2.namedWindow("img", 1) #新建一个显示窗口
cv2.resizeWindow("img", 800, 400) #图像框的大小
img = ep_camera.read_cv2_image()#获取视频流的一帧图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#将读取到的值转化为灰度图
faces = face_cascade.detectMultiScale(gray,1.1,5)#检测出图片中所有的人脸,并将人脸的各个坐标保持到faces里
if len(faces)>0:#判断是否检测到人脸
for faceRect in faces: #依次读取faces的值
x,y,w,h = faceRect
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),3)#绘制人脸框
roi_gray = gray[y:y+h//2,x:x+w]
roi_color = img[y:y+h//2,x:x+w]
RLzhongxi_x = x+w/2 #获取人脸中心坐标
RLzhongxi_y = y+h/2
eyes = eye_cascade.detectMultiScale(roi_gray,1.1,1,cv2.CASCADE_SCALE_IMAGE,(2,2))#检测眼睛
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)#绘制眼睛框
cv2.imshow("img",img)#显示图像
cv2.waitKey(2)#每两帧的间隔时间
return RLzhongxi_x,RLzhongxi_y#返回人脸中心坐标
def Error():
RLzhongxi_x_1=centre[0]#将上面的值传到这里
RLzhongxi_y_1=centre[1]
TXzhongxi_x=400 #整个图像的中心坐标
TXzhongxi_y=200
error_x=TXzhongxi_x-RLzhongxi_x_1 #偏航轴的的误差
error_y=TXzhongxi_y-RLzhongxi_y_1#俯仰轴的误差
if abs(error_x) < 10:#判断误差是否小于10,如果小于默认为到达人脸中心
yaw0_speed = 0
else:
yaw0_speed = KP*error_x#输出偏航轴的速度
if abs(error_y) < 10:
pitch0_speed = 0
else:
pitch0_speed = -KP*error_y#输出俯仰轴的速度
print("yaw的速度:",yaw0_speed)
print("Pitch的速度:",pitch0_speed)
ep_gimbal.drive_speed(pitch_speed='{pitch}', yaw_speed='{yaw}'.format(pitch=pitch0_speed,yaw=yaw0_speed))#控制云台
while True:
shibei()
centre = shibei()
Error()
因为EP借出去了,没有测试过新版的SDK,以前就旧的SDK是可以用的,如果有问题,希望大家指正,谢谢,