Two camera objects in Flask app provides freeze

asked 2020-02-27 04:03:18 -0600

updated 2020-02-27 04:35:13 -0600

supra56 gravatar image

Hello

I have created flask app which uses two objects of opencv cameras. At the start I am creating cameras objects and stores them in a list. Added debug print statement just to know that my cameras are created. However just after flask start I can see that only one camera is created and whole app freezes. Checked that on my desktop computer and it's working, but sometimes I can see my debug print four times, instead of two, which is very weird.

Code look's like this:

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

and 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 ...
(more)
edit retag flag offensive close merge delete