Я создал приложение flask, которое использует два объекта камер opencv. В начале я создаю объекты камер и сохраняю их в списке. Добавлен оператор печати отладки, чтобы знать, что мои камеры созданы. Однако сразу после запуска flask я вижу, что создана только одна камера и все приложение зависает. Проверил это на моем настольном компьютере, и он работает, но иногда я вижу отладочную печать четыре раза вместо двух, что очень странно.
Код выглядит следующим образом:
main.py
from flask import Blueprint, render_template, Response, abort, redirect, url_for
from flask_login import login_required, current_user
from . import db
from .CamerasPool import CamerasPool
from .models import User
import cv2
main = Blueprint('main', __name__)
# Create two cameras
camerasPool = CamerasPool()
camerasPool.registerCamera(0, False)
camerasPool.registerCamera(1, True)
@main.route('/')
def index():
return render_template('index.html')
@main.route('/profile', methods=["POST", "GET"])
def profile():
if not current_user.is_authenticated:
abort(403)
return render_template('profile.html', name=current_user.name, id=current_user.id)
@main.route('/video_stream/<int:stream_id>')
def video_stream(stream_id):
if not current_user.is_authenticated:
abort(403)
print(f'Current user detection: {current_user.detectionState}')
print(f'Current user fisheye: {current_user.fisheyeState}')
global camerasPool
camera = camerasPool.getCamWithParameters(current_user.detectionState)
return Response(camera.gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
@main.route('/fisheye')
def fisheye():
if not current_user.is_authenticated:
abort(403)
global camerasPool
if current_user.fisheyeState:
current_user.fisheyeState = False
else:
current_user.fisheyeState = True
user = User.query.filter_by(id=current_user.id)
user.fisheyeState = current_user.fisheyeState
db.session.commit()
return redirect(url_for('main.profile', id=current_user.id, user_name=current_user.name))
@main.route('/detection')
def detection():
if not current_user.is_authenticated:
abort(403)
global camerasPool
if current_user.detectionState:
current_user.detectionState = False
else:
current_user.detectionState = True
user = User.query.filter_by(id=current_user.id)
user.detectionState = current_user.detectionState
db.session.commit()
return redirect(url_for('main.profile', id=current_user.id, user_name=current_user.name))
@main.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@main.errorhandler(403)
def page_forbidden(e):
return render_template('403.html'), 403
CamerasPool.py
from .CameraHandler import CameraHandler
import cv2
class CamerasPool:
def __init__(self):
self.__cameras = []
def registerCamera(self, id, detection):
self.__cameras.append(CameraHandler(id, cv2.VideoCapture(0), detection))
print('Camera registered')
def getCamWithParameters(self, detection):
camera = None
for cam in self.__cameras:
if cam.getDetectionState() == detection:
# if cam.getFisheyeState() == fisheye:
camera = cam
break
return camera
и CameraHandler.py
import cv2
class CameraHandler():
def __init__(self, id, cam, detectionState):
self.id = id
self.cam = cam
self.current_frame = None
self.__shouldDetect = detectionState
self.__shouldRemoveFisheye = False
print('Camera created')
def __del__(self):
self.cam.release()
def getDetectionState(self):
return self.__shouldDetect
def getFisheyeState(self):
return self.__shouldRemoveFisheye
def __detectFace(self, img):
faces, confidences = cv.detect_face(img)
for face in faces:
(startX, startY) = face[0], face[1]
(endX, endY) = face[2], face[3]
cv2.rectangle(img, (startX, startY), (endX, endY), (0, 255, 0), 2)
return img
def __removeFisheye(self, img):
# TO DO
return img
def __getFrame(self):
rval, frame = self.cam.read()
if rval:
frame = cv2.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
try:
if self.__shouldRemoveFisheye:
frame = self.__removeFisheye(frame)
except:
print('Fisheye effect exception')
try:
if self.__shouldDetect:
frame = self.__detectFace(frame)
except:
print('Face detection exception')
cv2.imwrite('t.jpg', frame)
(flag, encodedImage) = cv2.imencode(".jpg", frame)
self.current_frame = bytearray(encodedImage)
def gen(self):
while True:
self.__getFrame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + self.current_frame + b'\r\n')
Я использую его на RPi 4B с новейшим Raspbian. Сразу после запуска загрузка процессора на малине показывает 100%, но я не могу поверить, что что-то подобное слишком много для малины. Если этого кода недостаточно: вот мои git со всем проектом: Проект .
Заранее спасибо за подсказки