Skip to content

FileVideoStream puts an NoneType into the queue #251

@KanTakahiro

Description

@KanTakahiro

I read this article and write a code like this (almost the same code as the article showed):

# import the necessary packages
from imutils.video import FileVideoStream
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", required=True, help="path to input video file")
args = vars(ap.parse_args())
# start the file video stream thread and allow the buffer to
# start to fill
print("[INFO] starting video file thread...")
fvs = FileVideoStream(args["video"]).start()
time.sleep(1.0)
# start the FPS timer
fps = FPS().start()

# loop over frames from the video file stream
while fvs.more():
    # grab the frame from the threaded video file stream, resize
    # it, and convert it to grayscale (while still retaining 3
    # channels)
    frame = fvs.read()
    frame = imutils.resize(frame, width=640)
    '''
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame = np.dstack([frame, frame, frame])
    '''
    # display the size of the queue on the frame
    cv2.putText(frame, "Queue Size: {}".format(fvs.Q.qsize()), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
    # show the frame and update the FPS counter
    cv2.imshow("Frame", frame)
    cv2.waitKey(1)
    fps.update()

# stop the timer and display FPS information
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# do a bit of cleanup
cv2.destroyAllWindows()
fvs.stop()

I run this code with python3 test.py -v video.mp4 and the script does playback the all video but finally an error was thrown out:

[INFO] starting video file thread...
Traceback (most recent call last):
  File "neo.py", line 27, in <module>
    frame = imutils.resize(frame, width=640)
  File "/home/takahiro/.local/lib/python3.8/site-packages/imutils/convenience.py", line 69, in resize
    (h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'

It seems that a NoneType was fed to the function imutils.resize() instead of a available frame. Since all the frames are fetched from the queue in FileVideoStream, I found the reason that causes this error in the implementation of FileVideoStream.
In function update() of imutils/video/filevideostream.py, if cv2.VideoCapture().read() faild(that basically means it reached the end of video file), although self.stopped is set to be True, self.Q.put(frame) in the below is still executed and put a NoneType into the queue. The process won't stop until the next loop start, but in this case it should be stopped immediately, at least before the self.Q.put(frame).
The original filevideostream.py, with all comments and empty lines deleted:

def update(self):
	while True:
		if self.stopped:
			break
		if not self.Q.full():
			(grabbed, frame) = self.stream.read()
			if not grabbed:
				self.stopped = True
			if self.transform:
				frame = self.transform(frame)
			self.Q.put(frame)
		else:
			time.sleep(0.1)  # Rest for 10ms, we have a full queue
	self.stream.release()

I added a continue under self.stopped = True to avoid self.Q.put(frame) from executing and the error didn't appear any more.
I don't know whether it is a bug of FileVideoStream. Maybe this solution will cause another issue. But if someone using FileVideoStream meets the same error then you can try this solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions