Flask app working really slow with opencv
One of the issue which even I had was regrading the encoding and decoding. Like the encoder of Opencv is too slow so try to use encoder from simplejpeg. Use pip3 install simplejpeg and with respect to using cv2.imencode() use simplejpeg.encode_jpeg()
One option is using
VideoStream
The reason VideoCapture is so slow because the VideoCapture pipeline spends the most time on the reading and decoding the next frame. While the next frame is being read, decode, and returned the OpenCV application is completely blocked.
VideoStream
solves the problem by using a queue structure, concurrently read, decode, and return the current frame.VideoStream
supports bothPiCamera
andwebcam
.
All you need to is:
- Install
imutils
:
- Install
For virtual environment:
pip install imutils
For anaconda environment:
conda install -c conda-forge imutils
- Initialize
VideoStream
onmain.py
- Initialize
import timefrom imutils.video import VideoStreamvs = VideoStream(usePiCamera=True).start() # For PiCamera# vs = VideoStream(usePiCamera=False).start() # For Webcamcamera = Camera(vs, framesNormalQue, framesDetectionQue)
- In your
Camera.py
- In your
- In
run(self)
method:
* ```python def run(self): while True: frame = self.__cam.read() frame = cv2.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA) _, jpeg = cv2.imencode('.jpg', frame) self.__normalQue.put(jpeg.tobytes()) self.__detectedQue.put(deepcopy(jpeg.tobytes())) if self.__shouldStop: break ```
I'm not really surprised about your problem, in general "detection" using a lot of your computation time, becauseperforming a cascaded classification algorithm is a demanding computational task.I found a source which compares cascaded classification algos for there performance link
An easy solution, would be to reduce the frame rate, whenprocessing your detection.An easy implementation to reduce performance demand could be something like a skip counter e.g.
frameSkipFactor = 3 # use every third frameframeCounter = 0if (frameCounter%frameSkipFactor==0): #processelse: print("ignore frame", frameCounter)frameCounter+=1
Nevertheless you will have a lag, because the detection calculationwill produce always a time offset.I you planning to construct a "real time" classification camera system, please look for another class of classification algos,which are more designed for this use-case.I followed an discussion here: real time class algos
Another solution could be using a bigger "hardware hammer" than the rpi e.g. an GPU implementation of the algo via Cuda etc.