0

I am having difficulty getting my video feed to work. I am trying to do simple object detection roughly following this tutorial, but have come across an issue. For some reason, the imshow windows aren't updating, they just keep showing the first frame. Any idea why? I am using cv2.VideoCapture and updating the frames every loop.

From what I can tell, the frames are successfully updating, as if I hold my hand up close to the camera, I can see the output values for frames changing down to [0,0,0,]ish, and when I take it away, they shoot back up as color comes back in.

Here is my code:

# Imports
from imutils.video import VideoStream
import numpy as np
import cv2
import imutils
import time

# CONSTANTS
MIN_AREA = 500

vs = cv2.VideoCapture(0)
#vs = VideoStream(src=0).start()
time.sleep(2)
firstFrame = None
secondFrame = None

while True:
    frame = vs.read()
    if frame[0] is False: # If read returned False, there was no frame to grab.
        print("Error getting frame")
        exit()
    else: # Gets the image
        frame = frame[1]
        
    #Resize to make the image less intensive to process
    frame = imutils.resize(frame, width=500)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Convert to gray to make the image easier to run through Gaussian blur.
    gray = cv2.GaussianBlur(gray, (21, 21), 0) # Smooths out the pixels to get rid of any high variation between pixel intensities in a given region (x, x)
    # Makes sure I am always comparing the last 2 frames in
    if firstFrame is None:
        print("Entered 1st")
        firstFrame = gray
        continue
    elif secondFrame is None:
        print("Entered 2nd")
        secondFrame = gray
    else:
        print("Entered else")
        firstFrame = secondFrame
        secondFrame = gray;
    
    # Compute Abs diffrence between current frame and first frame.
    frameDelta = cv2.absdiff(firstFrame,secondFrame) # Simple subtraction of pixel intensities
    thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1] # Thresholding the frameDelta. Only showing changes greater than x pixels, given by 2nd parameter argument.

    thresh = cv2.dilate(thresh, None, iterations=2)
    contours = cv2.findContours(thresh.copy(), cv2. RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = imutils.grab_contours(contours)
    
    # Loop over the contours.
    # If the current contour is too small, ignore it
    for c in contours:
        if cv2.contourArea(c) < MIN_AREA:
            continue
        # Else a bounding box is drawn around it
        (x, y, w, h) = cv2.boundingRect(c)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    
    # Showing frames
    cv2.imshow("Normal",frame)
    cv2.imshow("Thresh",thresh)
    cv2.imshow("Frame Delta", frameDelta)

vs.release()
cv2.destroyAllWindows()
Caleb Renfroe
  • 183
  • 1
  • 13

1 Answers1

0

Found the answer!

Apparently, I needed to add this code

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

Although I don't know why?

Caleb Renfroe
  • 183
  • 1
  • 13
  • This is because the OpenCV HighGUI library needs time to process and draw the image to the screen. By not putting in a `cv2.waitKey()` call, the window never gets updated. I've flagged a duplicate for you to look at. – rayryeng Jun 24 '20 at 18:19