Search code examples
pythonopencvobject-detectionvideo-capture

VideoCapture does not play the video


I have a problem with VideoCapture where the video I am streaming shows only the 1st frame. In the following code I superimpose a video on top of the bounding box yielded from object detection:

if view_img:
            ####video_name is a path to my video 
            img = cv2.VideoCapture(video_name)
            ret_video, frame_video = img.read()
            if not ret_video: ######so that the video can be played in a loop
                img = cv2.VideoCapture(video_name)
                ret_video, frame_video = img.read()
            
            ###here I look for the bounding boxes and superimpose the video 
            hsv = cv2.cvtColor(im0, cv2.COLOR_BGR2HSV)
            mask = cv2.inRange(hsv, (0, 120, 120), (10, 255, 255))#(110, 120, 120), (130, 255, 255))#<- blue # RED: (0, 120, 120), (10, 255, 255)) 
            thresh = cv2.dilate(mask, None, iterations=2)
            contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            #contours = contours[0]
            contours = imutils.grab_contours(contours)
            #frame_counter = 0
            for contour in contours:
                if cv2.contourArea(contour) < 750:
                    continue
                (x, y, w, h) = cv2.boundingRect(contour)                                        
                height = 480
                width = 640                                     
                if y + h < height and x + w < width:                                            
                        logo = cv2.resize(frame_video, (w, h))###frame_video is the frame from the video which I superimpose
                        img2gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
                        _, logo_mask = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY)
                        roi = im0[y:y+h, x:x+w]
                        roi[np.where(logo_mask)] = 0
                        roi += logo            
        cv2.imshow(str(p), im0)# im0 is the webcam frame         
        cv2.waitKey(25)

What happens when I run this code, is that instead of showing the entire video on top of the webcam frame, it displays only the first frame of that video.

Superimposing video works fine in another script, modified original: source

I believe that the issue has something to do with waitKey() for the superimposed video, as it is not specified.

If I try to initialize the video with while (cap.isopened()): or while (True) then the program freezes and there is no output at all.


Solution

  • I didn't test it. You simply do like this: Btwe

    if view_img:
                ####video_name is a path to my video 
                img = cv2.VideoCapture(video_name)
                while img.isOpened():
                    ret_video, frame_video = img.read()
                    if not ret_video: ######so that the video can be played in a loop
                        break
                    
                    ###here I look for the bounding boxes and superimpose the video 
                    hsv = cv2.cvtColor(im0, cv2.COLOR_BGR2HSV)
                    mask = cv2.inRange(hsv, (0, 120, 120), (10, 255, 255))#(110, 120, 120), (130, 255, 255))#<- blue # RED: (0, 120, 120), (10, 255, 255)) 
                    thresh = cv2.dilate(mask, None, iterations=2)
                    contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
                    #contours = contours[0]
                    contours = imutils.grab_contours(contours)
                    #frame_counter = 0
                    for contour in contours:
                        if cv2.contourArea(contour) < 750:
                            continue
                        (x, y, w, h) = cv2.boundingRect(contour)                                        
                        height = 480
                        width = 640                                     
                        if y + h < height and x + w < width:                                            
                                logo = cv2.resize(frame_video, (w, h))###frame_video is the frame from the video which I superimpose
                                img2gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
                                _, logo_mask = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY)
                                roi = im0[y:y+h, x:x+w]
                                roi[np.where(logo_mask)] = 0
                                roi += logo            
                    cv2.imshow(str(p), im0)# im0 is the webcam frame         
                    cv2.waitKey(25)
    

    Btw, If you are using OpenCV4.5.5. You may have to add this:

    ret,contours = cv2.findContours