场景:

多幕监控,http接口的形式,socket服务端,html窗口显示多屏

服务端:esp32_cam_apiVideo,通过IP.txt配置连接客户端IP

esp32-cam板子客户端:esp32_cam_client.py

环境:

服务端:树莓派4B(Linux,python3.8)

客户端:MicroPython v1.18-74-gfeeeb5ea3(micropython_camera_feeeb5ea3_esp32_idf4_4.bin固件)

需求:

1.多个esp32-cam视频监控,将视频传输到服务端

2.树莓派显示全部的监控窗口

3.进行人脸检测,录制人脸,人脸识别(opencv视频帧处理)

4.进行车牌号识别(opencv视频帧处理)

5.进行动植物识别,可忽略(opencv视频帧处理) 

1.树莓派socket服务端 

#网络视频流,以下代码是树莓派socket服务端
from flask import Flask, render_template, Response
import cv2
import socket
import numpy as np
import io
from PIL import Image
app = Flask(__name__)

CAPTURE_IMAGE_DATA = None
CAPTURE_IMAGE_DATAS = None
user_ip = {}
@app.route('/')
def index():
    return render_template('index.html')
       
def gen():
    global CAPTURE_IMAGE_DATA
    try:
        while True:
            yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + CAPTURE_IMAGE_DATA.tobytes() + b'\r\n')
    except Exception:
        print('CAPTURE_IMAGE_DATA缓存')
        CAPTURE_IMAGE_DATA = None
@app.route('/server')
def server():
    global CAPTURE_IMAGE_DATA
    global CAPTURE_IMAGE_DATAS
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server_socket.bind(("0.0.0.0", 9090))
    # 开始监听连接
    print('等待客户端连接...')
    try: 
        while True:
            data, IP = server_socket.recvfrom(100000)  # 接收数据,设置数据包大小。图片大小100K
            bytes_stream = io.BytesIO(data)  # 收到数据后转为字节流
            image = Image.open(bytes_stream)  # 打开这个图片
            img = np.asarray(image)  # 转化为数组格式
            img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)  # ESP32采集的是RGB格式,要转换为BGR(opencv的格式)如果需要)
            # 转换为JPEG格式
            _, jpeg = cv2.imencode('.jpg', img)
            if IP[0] in user_ip['addres']:
                CAPTURE_IMAGE_DATA = jpeg 
            if IP[0] in user_ip['addres2']:
                CAPTURE_IMAGE_DATAS = jpeg 
    except Exception:
        print('socket服务启动失败')
        return 'socket服务启动失败'
    finally:
        # 关闭服务器套接字
        server_socket.close() 

@app.route('/video_feed')
def video_feed():
    if CAPTURE_IMAGE_DATA is None:
        return 'IP配置错误或者无socket客户端连接'
    return Response(gen(),mimetype='multipart/x-mixed-replace; boundary=frame')
    

def print_routes():
    print("-----------打印所有的接口-----------")
    print(f"服务:http://127.0.0.1:5000/server")
    print(f"窗口1:http://127.0.0.1:5000/video_feed")
    print(f"多个窗口:http://127.0.0.1:5000")

#配置文件IP.txt只能设置两个IP,对应得IP变量必须是addres和addres2
def user_name_fun():
    global user_ip
    global ip
    f = open('IP.txt','r', encoding='utf-8')
    addres_arr =['addres','addres2']
    for i in range(2):
        line = f.readline()
        id_names = line.split(' ')
        if id_names[0] not in addres_arr:
            exit('IP配置错误...') 
        user_ip[id_names[0]] = id_names[1].strip()       
    f.close()
    print('--------------全部人员----------')
    print(user_ip)


if __name__ == '__main__':
    print_routes()
    user_name_fun()
    # from gevent import pywsgi
    # from gevent import monkey
    # from geventwebsocket.handler import WebSocketHandler
    try:
        # monkey.patch_all()
        # server = pywsgi.WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler)
        # server.serve_forever()
        app.run(host='0.0.0.0',port=5000,debug=False)
    except KeyboardInterrupt:
        print('程序已停止')     

2.esp32客户端

#socket客户端
import socket
import network
import camera
import time

 
ssid = 'UTT-HIPER_GZ'
password = 'guanzheng888'

# 连接wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
    print('connecting to network...')
    wlan.connect(ssid, password)
    while not wlan.isconnected():
        pass
    
wlan.ifconfig(
    ('192.168.0.48', '255.255.255.0', '192.168.0.1', '192.168.0.1')
)

print('网络配置:', wlan.ifconfig())
 
 
# 摄像头初始化
try:
    camera.init(0, format=camera.JPEG)
except Exception as e:
    camera.deinit()
    camera.init(0, format=camera.JPEG)
 
 
# 其他设置:
# 上翻下翻
camera.flip(0)
#左/右
camera.mirror(1)
 
# 分辨率
camera.framesize(camera.FRAME_HVGA)
# 选项如下:
# FRAME_96X96 FRAME_QQVGA FRAME_QCIF FRAME_HQVGA FRAME_240X240
# FRAME_QVGA FRAME_CIF FRAME_HVGA FRAME_VGA FRAME_SVGA
# FRAME_XGA FRAME_HD FRAME_SXGA FRAME_UXGA FRAME_FHD
# FRAME_P_HD FRAME_P_3MP FRAME_QXGA FRAME_QHD FRAME_WQXGA
# FRAME_P_FHD FRAME_QSXGA
# 有关详细信息,请查看此链接:https://bit.ly/2YOzizz
 
# 特效
camera.speffect(camera.EFFECT_NONE)
#选项如下:
# 效果\无(默认)效果\负效果\ BW效果\红色效果\绿色效果\蓝色效果\复古效果
# EFFECT_NONE (default) EFFECT_NEG \EFFECT_BW\ EFFECT_RED\ EFFECT_GREEN\ EFFECT_BLUE\ EFFECT_RETRO
 
# 白平衡
camera.whitebalance(camera.WB_HOME)
#选项如下:
# WB_NONE (default) WB_SUNNY WB_CLOUDY WB_OFFICE WB_HOME
 
# 饱和
camera.saturation(0)
#-2,2(默认为0). -2灰度
# -2,2 (default 0). -2 grayscale 
 
# 亮度
camera.brightness(0)
#-2,2(默认为0). 2亮度
# -2,2 (default 0). 2 brightness
 
# 对比度
camera.contrast(0)
#-2,2(默认为0).2高对比度
#-2,2 (default 0). 2 highcontrast
 
# 质量
camera.quality(10)
#10-63数字越小质量越高
 
# socket UDP 的创建
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
 
try:
    while True:
        buf = camera.capture()  # 获取图像数据
        s.sendto(buf, ("192.168.0.9", 9090))  # 向服务器发送图像数据。这个IP地址是电脑的IP地址
        time.sleep(0.05)
except:
    pass
finally:
    camera.deinit()

更多推荐