Flask зависает при старте на RPi - PullRequest
0 голосов
/ 26 февраля 2020

Я создал приложение 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 со всем проектом: Проект .

Заранее спасибо за подсказки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...