0

Trying to execute a conditional statement on the basis of value provided by html form.

The flow of the code is as follows. Index.html gets rendered with a videostream and has a checkbox to let the user decide wether they want to run face detection or not.

On pressing the check button flask saves the value to a variable called status, and tries to pass it during the opencv_camera object. All my attempts yield self/status not defined.

Really lost please help.

camera_opencv.py

from base_camera import BaseCamera
**# THE CLASS IN QUESTION**
class Camera(BaseCamera):
    status = 0
    def __init__(self, state=None):
        if state:
                status = state
        else:
            status = 0
        super().__init__()
    video_source = 0
    @staticmethod
    def set_video_source(source):
        Camera.video_source = source

    @staticmethod
    def frames():
        camera = cv2.VideoCapture(Camera.video_source)
        if not camera.isOpened():
            raise RuntimeError('Could not start camera.')

        while True:
            # read current frame
            _, frame = camera.read()
            # frame = cv2.resize(frame, (704, 396))
            if status: # CONDITIONAL STATEMENT
                gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

                faces = face_cascade.detectMultiScale(gray, 1.3, 5)
                if len(faces) > 0:
                    print("SUPS")
                for (x,y,w,h) in faces:
                    cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)



            # encode as a jpeg image and return it
            yield cv2.imencode('.jpg', frame)[1].tobytes()

app.py

   from camera_opencv import Camera
    app = Flask(__name__)
    state = 0 # STATE VARIABLE 
    @app.route('/', methods = ['GET','POST'])
    def index():
        state = request.form.get('check')
        # print(state)
        # import pdb; pdb.set_trace()
        return render_template("index.html")

    def gen(camera):
        """Video streaming generator function."""
        while True:
            frame = camera.get_frame()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

    @app.route('/video_feed')
    def video_feed():
        """Video streaming route. Put this in the src attribute of an img tag."""
        return Response(gen(Camera(state=state)),
                        mimetype='multipart/x-mixed-replace; boundary=frame')#STATE VARIABLE BEING PASSED
Miki
  • 40,887
  • 13
  • 123
  • 202
Rupaksh Paul
  • 112
  • 1
  • 11

1 Answers1

3

By their nature, web servers are stateless: they don't know if two requests come from the same user or not so each response gets executed in its own context. That means that if you set the state from 0 to 1 in your index view and then go to your /video_feed view, the state will again be 0.

To have the proper value of state available when starting the camera, add the state as a parameter to the /video_feed view. So if you want to use face detection, navigate to the url /video_feed?state=1 and grab the state parameter from the url. If you don't want to activate face detection, navigate to /video_feed?state=0 or just /video_feed and use the default state.

tarikki
  • 2,166
  • 2
  • 22
  • 32
  • 1
    Thanks I think is a much better solution. I'm really new to web servers but your idea of statelessness is spot on. I hadn't even considered having multiple users on my stream. Thank you so much! – Rupaksh Paul Jan 17 '19 at 07:13