Arduino与Proteus仿真实例-人脸追踪及反馈到舵机转向控制仿真

人脸追踪及反馈到舵机转向控制仿真

文章目录

本文将演示如何通过OpenCV进行人脸检测、追踪并反馈到舵机转向控制。OpenCV检测到人脸后,实时跟踪人脸的移动方向,转换成XY坐标,通过串口反馈到Arduino,Arduino解析人脸坐标并驱动舵机转向。

在前面的文章中,对舵机的驱动作了详细的介绍,请参考:

在前面的文章中,通过OpenCV进行人脸检测作了详细的介绍,请参考:

1、仿真电路原理图

在这里插入图片描述

在仿真电路原理图中,我们使用了两个舵机,一个用于控制X方向转动,另一个控制Y方向转动。这两个电机分别连接到IO2和IO3。

2、仿真代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <Servo.h>
int data_x = 0;
int data_y = 0;
int data[1];

// 方向控制舵机
Servo myservo_x;
Servo myservo_y;


void setup() {
Serial.begin(9600);

// 绑定引脚
myservo_x.attach(2);
myservo_y.attach(3);

// 旋转到90度方向
myservo_x.write(90);
myservo_y.write(90);
}

void loop() {
while (Serial.available() >= 2) {
for (int i = 0; i < 2; i++) {
data[i] = Serial.read();
}
myservo_x.write(data[0]);
myservo_y.write(data[1]);
}

}

示例代码的逻辑非常简单,通过读取串口数据,然后将串口数据进行解析X方向和Y方向角度值:

1
2
3
4
5
6
for (int i = 0; i < 2; i++) {
data[i] = Serial.read();
}
myservo_x.write(data[0]);
myservo_y.write(data[1]);

3、人脸检测及追踪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import cv2
import numpy as np
import serial
import struct
import time
a=0
b=0
x=0
y=0
# 初始化串口
ser = serial.Serial('com2',9600)
time.sleep(2)

font=cv2.FONT_HERSHEY_SIMPLEX
# 加载人脸检测级联模型
FaceCascade=cv2.CascadeClassifier('haarcascade\_frontalface\_default.xml')
# 加载
cap=cv2.VideoCapture('09-head-pose-face-detection-female.mp4')
#cap=cv2.VideoCapture(0)

while True:
# 读取帧
ret,frame=cap.read()
# 镜像帧
flipit=cv2.flip(frame,1)
# 转换成灰度图像
gray=cv2.cvtColor(flipit,cv2.COLOR_BGR2GRAY)
# 检测人脸
face=FaceCascade.detectMultiScale(gray,1.2,4)
'''查找人脸位置'''
try:
for (x1,y1,w1,h1) in face:
a=int((2\*x1+w1)/2)
b=int((2\*y1+h1)/2)
x=int(a/3.66)
y=int(b/2.55)
# 向串口发送人脸位置
ser.write(struct.pack('>BB', x,y))
# 绘制人脸范围矩形
cv2.rectangle(flipit,(x1,y1),(x1+w1,y1+h1),(0,255,0),2)

except:
pass

cv2.imshow('flipit',flipit)
k=cv2.waitKey(20) & 0xff
if k==27:
break
cap.release()
cv2.destroyAllWindows()

在示例代码中,

第一步,导入必要库:

1
2
3
4
5
6
import cv2
import numpy as np
import serial
import struct
import time

第二步,初始化串口:

1
2
ser = serial.Serial('com2',9600)

第三步,加载人脸检测模型文件:

1
2
FaceCascade=cv2.CascadeClassifier('haarcascade\_frontalface\_default.xml')

第四步,打开视频文件或摄像头:

1
2
3
cap=cv2.VideoCapture('09-head-pose-face-detection-female.mp4')
#cap=cv2.VideoCapture(0)

第五步,读取视频或摄像头的帧:

1
2
3
4
5
# 读取帧
ret,frame=cap.read()
# 镜像帧
flipit=cv2.flip(frame,1)

第六步,检测人脸:

1
2
3
4
5
# 转换成灰度图像
gray=cv2.cvtColor(flipit,cv2.COLOR_BGR2GRAY)
# 检测人脸
face=FaceCascade.detectMultiScale(gray,1.2,4)

第七步,发送人脸坐标:

1
2
3
4
5
6
7
8
9
10
11
12
'''查找人脸位置'''
try:
for (x1,y1,w1,h1) in face:
a=int((2\*x1+w1)/2)
b=int((2\*y1+h1)/2)
x=int(a/3.66)
y=int(b/2.55)
# 向串口发送人脸位置
ser.write(struct.pack('>BB', x,y))
# 绘制人脸范围矩形
cv2.rectangle(flipit,(x1,y1),(x1+w1,y1+h1),(0,255,0),2)

4、仿真结果

在这里插入图片描述

在本次实例中,实现了原理性的仿真,但是级联人脸检测模型进行人脸检测对人脸的检测效果不是很理想,可以使用人工神经网络模型进行人脸检测,然后再将人脸偏移位置转换成舵机转向角度。

文章来源: https://iotsmart.blog.csdn.net/article/details/128573394