Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileVideoStream: do not call transform when stopping #119

Closed
wants to merge 1 commit into from
Closed

FileVideoStream: do not call transform when stopping #119

wants to merge 1 commit into from

Conversation

ghost
Copy link

@ghost ghost commented Feb 13, 2019

Fixes:

read_frames_fast.py -v /home/swarthout/packages/sw/opencv/opencv_extra/testdata/highgui/video/big_buck_bunny.wmv
[INFO] starting video file thread...
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.6/dist-packages/imutils/video/filevideostream.py", line 67, in update
frame = self.transform(frame)
File "read_frames_fast.py", line 21, in filterFrame
frame = imutils.resize(frame, width=450)
File "/usr/local/lib/python3.6/dist-packages/imutils/convenience.py", line 69, in resize
(h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'

[INFO] elasped time: 0.31
[INFO] approx. FPS: 402.98

Signed-off-by: Ed Swarthout Ed.Swarthout@nxp.com

@abhiTronix
Copy link
Contributor

abhiTronix commented Feb 18, 2019

@Ed-Swarthout-NXP

read_frames_fast.py -v /home/swarthout/packages/sw/opencv/opencv_extra/testdata/highgui/video/big_buck_bunny.wmv
[INFO] starting video file thread...
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.6/dist-packages/imutils/video/filevideostream.py", line 67, in update
frame = self.transform(frame)
File "read_frames_fast.py", line 21, in filterFrame
frame = imutils.resize(frame, width=450)
File "/usr/local/lib/python3.6/dist-packages/imutils/convenience.py", line 69, in resize
(h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'

This error simply means that the path to video file is wrong or missing, not related to do not call transform when stopping, as you suspected .

@ghost
Copy link
Author

ghost commented Feb 19, 2019

@Ed-Swarthout-NXP

read_frames_fast.py -v /home/swarthout/packages/sw/opencv/opencv_extra/testdata/highgui/video/big_buck_bunny.wmv
[INFO] starting video file thread...
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.6/dist-packages/imutils/video/filevideostream.py", line 67, in update
frame = self.transform(frame)
File "read_frames_fast.py", line 21, in filterFrame
frame = imutils.resize(frame, width=450)
File "/usr/local/lib/python3.6/dist-packages/imutils/convenience.py", line 69, in resize
(h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'

This error simply means that the path to video file is wrong or missing, not related to do not call transform when stopping, as you suspected .

I see the video play before the error occurs at the end - so the path to the video file is correct.
Are you saying the error does not occur in your environment?

@abhiTronix
Copy link
Contributor

abhiTronix commented Feb 19, 2019

I see the video play before the error occurs at the end - so the path to the video file is correct.
Are you saying the error does not occur in your environment?

Ok, So you're experiencing this problem when the video ends. So you can easily handle that with the code as below:

from imutils.video import FileVideoStream
cam = FileVideoStream('/home/test.mp4').start()
while True: 
	frame = cam.read()
	if frame is None: #check for file end 
	      break  #safely breaks out if end reaches
cv2.destroyAllWindows()
cam.stop()

thereby we can now check for File End and then exit safely. Related Merged PR is here #102. Try this, There is no need for this PR.

@ghost
Copy link
Author

ghost commented Feb 19, 2019

I see the video play before the error occurs at the end - so the path to the video file is correct.
Are you saying the error does not occur in your environment?

Ok, So you're experiencing this problem on when the video ends. So you can easily handle that with the code as below:

from imutils.video import FileVideoStream
cam = FileVideoStream('/home/test.mp4').start()
while True: 
	frame = cam.read()
	if frame is None: #check for file end 
	      break  #safely breaks out if end reaches
cv2.destroyAllWindows()
cam.stop()

thereby we can now check for File End and then exit safely. Related PR is here #102. Try this, There is no need for this PR.

But self.tranform() is called before read() returns.
It should not be called if there is no frame to process.

@abhiTronix
Copy link
Contributor

abhiTronix commented Feb 19, 2019

But self.tranform() is called before read() returns.
It should not be called if there is no frame to process.

Nope, before self.transform(), self.stopped flag is there, that gets activate when there is no frame(grabbed), that breaks loop and also self.stream.release() is called which means Videostream/self.stream releases, see below:

while True:
			# if the thread indicator variable is set, stop the
			# thread
			if self.stopped:
				break

			# otherwise, ensure the queue has room in it
			if not self.Q.full():
				# read the next frame from the file
				(grabbed, frame) = self.stream.read()

				# if the `grabbed` boolean is `False`, then we have
				# reached the end of the video file
				if not grabbed:
					self.stopped = True
					
				# if there are transforms to be done, might as well
				# do them on producer thread before handing back to
				# consumer thread. ie. Usually the producer is so far
				# ahead of consumer that we have time to spare.
				#
				# Python is not parallel but the transform operations
				# are usually OpenCV native so release the GIL.
				#
				# Really just trying to avoid spinning up additional
				# native threads and overheads of additional
				# producer/consumer queues since this one was generally
				# idle grabbing frames.
				if self.transform:
					frame = self.transform(frame)

				# add the frame to the queue
				self.Q.put(frame)
                      self.stream.release()

and After breaking from the main loop(as suggested in my previous comment), you call cam.stop() and therefore all the underlying processes gets destroyed and self.thread thread get joined safely. Here is that function:

def stop(self):
		# indicate that the thread should be stopped
		self.stopped = True
		# wait until stream resources are released (producer thread might be still grabbing frame)
		self.thread.join()

Since VideoStream thread will be released and closed already, there will be simply no threading error!

@BCLegon
Copy link

BCLegon commented May 20, 2019

The loop is indeed ended when self.stopped is set to True because no frames were grabbed.

But the real problem here is that the frame is still being transformed and even put in the queue, even though we know for sure that its value will be None at this point.

This is solved by adding a simple else: line.

In case of doubt, be sure to check the commit itself and the explanation in #137.

Fixes:

read_frames_fast.py -v /home/swarthout/packages/sw/opencv/opencv_extra/testdata/highgui/video/big_buck_bunny.wmv
[INFO] starting video file thread...
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.6/dist-packages/imutils/video/filevideostream.py", line 67, in update
    frame = self.transform(frame)
  File "read_frames_fast.py", line 21, in filterFrame
    frame = imutils.resize(frame, width=450)
  File "/usr/local/lib/python3.6/dist-packages/imutils/convenience.py", line 69, in resize
    (h, w) = image.shape[:2]
AttributeError: 'NoneType' object has no attribute 'shape'

[INFO] elasped time: 0.31
[INFO] approx. FPS: 402.98

Signed-off-by: Ed Swarthout <Ed.Swarthout@nxp.com>
@ghost
Copy link
Author

ghost commented May 23, 2019

Despite the comments to the contrary, this issue still exists and somebody else had to debug and generate their own pull request. See #137

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants