【V2.0】基于树莓派的OpenCV-Python摄像头人脸追踪及手势识别、网络地址推流及远程控制系统(多功能系统、含演示视频)
前文:
https://blog.csdn.net/weixin_53403301/article/details/124193033
资源:
https://download.csdn.net/download/weixin_53403301/85142311
该系统目前结合了树莓派+51单片机和树莓派树莓派独立两个版本
树莓派主要用于运行Python程序 追踪人脸 同时用GPIO口给出信号
单片机用于控制42步进电机导轨左右移动
树莓派独立版本则直接控制步进电机导轨
【V1.1】基于树莓派的OpenCV-Python摄像头人脸追踪系统(更新系统、含演示视频)
先前的文章:
https://blog.csdn.net/weixin_53403301/article/details/122898050
人脸追踪部分:
https://blog.csdn.net/weixin_53403301/article/details/120497427
单片机控制42步进电机导轨部分:
https://blog.csdn.net/weixin_53403301/article/details/122658780
软件部分最新文章:
https://blog.csdn.net/weixin_53403301/article/details/124193033
树莓派直接控制步进电机文章:
https://blog.csdn.net/weixin_53403301/article/details/124192914
树莓派+单片机部分代码预览如下:
import cv2
from flask import Flask, render_template, Response, request
import threading
import socket
import mediapipe as mp
import math
import time
import RPi.GPIO as GPIO
global q
q = 0
global kill_all_flag
kill_all_flag = 0
global model_flag
model_flag = 0
global command_str
command_str = None
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(6, GPIO.OUT) #zz
GPIO.setup(13, GPIO.OUT) #fz
GPIO.setup(19, GPIO.OUT) # reset
GPIO.setup(26, GPIO.OUT) # set
GPIO.output(6,1)
GPIO.output(13,1)
GPIO.output(19,1)
GPIO.output(26,1)
local_post = 1212
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.connect(("8.8.8.8",80))
local_ip = str(s.getsockname()[0])
s.close()
app = Flask(__name__)
cap = cv2.VideoCapture(0) # 开启摄像头
classifier = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
global cam_img
global faceImg
ok, cam_img = cap.read() # 读取摄像头图像
if ok is False:
q = 1
kill_all_flag = 1
print('无法读取到摄像头!')
faceImg = cam_img
high=faceImg.shape[0]
width=faceImg.shape[1]
left_point = width/2+25
right_point = width/2-25
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False,max_num_hands=1,min_detection_confidence=0.75,min_tracking_confidence=0.75)
def Right():
GPIO.output(6,0)
GPIO.output(13,1)
GPIO.output(19,1)
GPIO.output(26,1)
print("Right")
def Left():
GPIO.output(6,1)
GPIO.output(13,0)
GPIO.output(19,1)
GPIO.output(26,1)
print("Left")
def Reset():
GPIO.output(6,1)
GPIO.output(13,1)
GPIO.output(19,0)
GPIO.output(26,1)
print("Reset")
def Set():
GPIO.output(6,1)
GPIO.output(13,1)
GPIO.output(19,1)
GPIO.output(26,0)
print("Set")
def Stop():
GPIO.output(6,1)
GPIO.output(13,1)
GPIO.output(19,1)
GPIO.output(26,1)
print("Stop")
树莓派独立控制部分预览代码如下:
import cv2
from flask import Flask, render_template, Response, request
import threading
import socket
import mediapipe as mp
import math
import time
import RPi.GPIO as GPIO
global q
q = 0
global kill_all_flag
kill_all_flag = 0
global model_flag
model_flag = 0
global command_str
command_str = None
DJ_delay = 0.0015
DJ_buf = [[0,0],[0,1],[1,1],[1,0]]
global DJ_i
DJ_i = 0
DJ_size = 350
global DJ_jugg_flag
DJ_jugg_flag = 0
local_post = 1212
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.connect(("8.8.8.8",80))
local_ip = str(s.getsockname()[0])
s.close()
app = Flask(__name__)
cap = cv2.VideoCapture(0) # 开启摄像头
classifier = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
global cam_img
global faceImg
ok, cam_img = cap.read() # 读取摄像头图像
if ok is False:
q = 1
kill_all_flag = 1
print('无法读取到摄像头!')
faceImg = cam_img
high=faceImg.shape[0]
width=faceImg.shape[1]
left_point = width/2+25
right_point = width/2-25
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False,max_num_hands=1,min_detection_confidence=0.75,min_tracking_confidence=0.75)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(16, GPIO.OUT)
GPIO.setup(20, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)
GPIO.output(16,0)
GPIO.output(20,0)
GPIO.output(21,0)
def DJ_zz():
global DJ_i
time.sleep(DJ_delay)
GPIO.output(16,DJ_buf[DJ_i][0])
GPIO.output(20,1)
GPIO.output(21,DJ_buf[DJ_i][1])
DJ_i = DJ_i + 1
if DJ_i == 4:
DJ_i = 0
def DJ_fz():
global DJ_i
time.sleep(DJ_delay)
GPIO.output(16,DJ_buf[DJ_i][0])
GPIO.output(20,1)
GPIO.output(21,DJ_buf[DJ_i][1])
DJ_i = DJ_i - 1
if DJ_i == -1:
DJ_i = 3
def DJ_jugg():
global DJ_jugg_flag
DJ_jugg_flag = 0
DJ_flag = 0
GPIO.output(16,0)
GPIO.output(20,0)
GPIO.output(21,0)
while True:
if DJ_jugg_flag == 0:
time.sleep(0.1)
GPIO.output(16,0)
GPIO.output(20,0)
GPIO.output(21,0)
else:
while DJ_jugg_flag == 1:
if DJ_flag < DJ_size:
DJ_zz()
DJ_flag = DJ_flag +1
else:
DJ_flag = DJ_size
while DJ_jugg_flag == 2:
if DJ_flag > -DJ_size:
DJ_fz()
DJ_flag = DJ_flag -1
else:
DJ_flag = -DJ_size
if DJ_jugg_flag == 3:
while DJ_flag > 0:
DJ_fz()
DJ_flag = DJ_flag -1
while DJ_flag < 0:
DJ_zz()
DJ_flag = DJ_flag +1
DJ_flag = 0
elif DJ_jugg_flag == 4:
DJ_flag = 0
elif DJ_jugg_flag == 5:
DJ_jugg_flag = 0
GPIO.output(16,0)
GPIO.output(20,0)
GPIO.output(21,0)
break
else:
GPIO.output(16,0)
GPIO.output(20,0)
GPIO.output(21,0)
所用到的HTML文件代码如下:
<html>
<head>
<title>智能导播系统title>
head>
<body>
<h1>智能导播系统h1>
<form action="/" method="post" style="float:left">
<p>
<input type="submit" style="font-size:50px" name="auto" value="自动模式">
<input type="submit" style="font-size:50px" name="manu" value="手动模式">
p>
<p>
<input type="submit" style="font-size:50px" name="reset" value="复位导轨">
<input type="submit" style="font-size:50px" name="set" value="设置点位">
p>
<p>
<input type="submit" style="font-size:50px" name="left" value="左移导轨">
<input type="submit" style="font-size:50px" name="right" value="右移导轨">
p>
<p>
<input type="submit" style="font-size:50px" name="go_in" value="继续程序">
<input type="submit" style="font-size:50px" name="go_out" value="暂停程序">
p>
<p>
<input type="submit" style="font-size:50px" name="stop" value="停止导轨">
<input type="submit" style="font-size:50px" name="quit" value="全部退出">
p>
<p>
<input type="submit" style="font-size:50px" name="left_step" value="左移一步">
<input type="submit" style="font-size:50px" name="right_step" value="右移一步">
p>
form>
<img src="{{ url_for('video_feed') }}" height="540" style="float:left">
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h2>手势及功能说明h2>
<h4 style="color:red">起始手势——左/右手“5”:开启手势控制模式,其他手势控制功能仅在开启该模式时有效,若10秒内无任一手势控制操作,则需手势“5"解锁;五指全部打开。h4>
<h4 style="color:blue">自动模式——右手“Spider-Man”:该模式下自动识别人脸并追踪,手动模式操作不可用;打开拇指、食指、小指,闭合中指、无名指。h4>
<h4 style="color:green">手动模式——左手“Rock'n'Roll”:该模式下不进行识别人脸或追踪,手动模式操作可用;打开食指、小指,闭合拇指、中指、无名指。h4>
<h4 style="color:blue">复位导轨——右手“Thumb Up”:手动模式操作。使导轨复位到标记的初始位置;竖起拇指,其他闭合。h4>
<h4 style="color:blue">设置点位——右手“Princess”:手动模式操作。标记导轨初始位置;打开中指、无名指、小指,闭合拇指、食指,又为“OK”手势。h4>
<h4 style="color:green">左移导轨——左手“2”:手动模式操作。左移导轨;竖起食指、中指,其他闭合。h4>
<h4 style="color:green">右移导轨——左手“1”:手动模式操作。右移导轨;竖起食指,其他闭合。h4>
<h4 style="color:blue">继续程序——右手“8”:恢复暂停的程序及功能;竖起拇指、食指,其他闭合。h4>
<h4 style="color:blue">暂停程序——右手“6”:暂停图像、识别、运动、手势功能,仅保留网页端控制功能;竖起拇指、小指,其他闭合。h4>
<h4 style="color:green">停止导轨——左手“0”:手动模式操作。停止导轨;全部闭合,握拳。h4>
<h4 style="color:red">全部退出——左/右手“Bye”:保持三秒即可退出所有程序,退出后无法执行任何功能;竖起拇指、食指、中指,其他闭合。h4>
<h4 style="color:green">左移一步——左手“4”:手动模式操作。左移一步;拇指闭合,其他打开。h4>
<h4 style="color:green">右移一步——左手“3”:手动模式操作。右移一步;拇指、小指闭合,其他打开。h4>
body>
html>