Search code examples
pythonopencvpython-3.xstreammjpeg

OpenCv Python frame empty in mjpeg stream from webcam


I'm creating a program that displays 4 mjpg cameras in a grid, my problem is that sometimes it happens that a frame is empty and the stream freeze, I capture the error by checking the size of each frame, and if it is equal to 1 I continue the cycle, my problem is that I remain in the control loop, it seems that the stream flow is not able to obtain a valid frame, any suggestion?

import socket
import numpy as np
import cv2

cap = cv2.VideoCapture("http://85.90.40.19/mjpg/video.mjpg")
cap2 = cv2.VideoCapture("http://85.90.40.19/mjpg/video.mjpg")
cap3 = cv2.VideoCapture("http://85.90.40.19/mjpg/video.mjpg")
cap4 = cv2.VideoCapture("http://85.90.40.19/mjpg/video.mjpg")



cv2.namedWindow('frame', cv2.WND_PROP_FULLSCREEN)

cv2.setWindowProperty('frame', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

while True:

    try:
         ret, frame = cap.read()
         ret2, frame2 = cap2.read()
         ret3, frame3 = cap2.read()
         ret4, frame4 = cap2.read()
     except:
         print("try catch")
         continue



     size = np.size(frame)
     size2 = np.size(frame2)
     size3 = np.size(frame3)
     size4 = np.size(frame4)


     if (size or size2 or size3 or size4) == 1:
        print("frame 0")
        continue

     # print("Dimensione" + str(size))

     rframe = cv2.resize(frame, (640,480))
     rframe2 = cv2.resize(frame2, (640,480))
     rframe3 = cv2.resize(frame3, (640,480))
     rframe4 = cv2.resize(frame4, (640,480))

     print(ret,ret2,ret3,ret4)


     vert1 = np.vstack((rframe,rframe2))
     vert2 = np.vstack((rframe3,rframe4))

     both = np.hstack((vert1,vert2))
     print(both.shape)
     # both.resize((1024, 768,3))

     cv2.imshow('frame', both)
     if cv2.waitKey(1) == 27:
         break

cap.release()
cv2.destroyAllWindows()

Thanks and sorry for my bad english


Solution

  • Could I suggest the following type of approach:

    try:
        ret, frame = cap.read()
    except:
        ret, frame = (-1, blackframe)
    
    try:
        ret2, frame2 = cap2.read()
    except:
        ret2, frame2 = (-1, blackframe)
    
    try:
        ret3, frame3 = cap3.read()
    except:
        ret3, frame3 = (-1, blackframe)
    
    try:
        ret4, frame4 = cap4.read()
    except:
        ret4, frame4 = (-1, blackframe)
    

    Where blackframe is a suitable image that you have available for when a capture fails. This would allow the other frames to continue to be displayed.

    The aim is to remove the continue statement which causes execution to return to the top without letting any of the other code execute.