opencv python Multi Threading Video Capture
*edit: I'll leave the code below, but I guess you have a codec problem? I installed the xvid codec (which is what the sample Megamind.avi is encoded with) and the program works fine with either or both threads running the megamind video. Can you get the megamind video to run in the single threaded version?
Here is an SO post on opencv video codecs in case it helps. Here is the xvid download that I used (k-lite didn't work for me).
The code you wrote basically works for me. For you and anyone else that wants to try, I did the following:
- applied PEP 8 recommendations
- removed the unnecessary read attempt code (which also removes the misleading thread re-read warnings after the last frame of a working video)
- used a video file that perhaps everyone with opencv has
- removed the thread locking which didn't seem to matter to opencv at least on my system
- moved a few other little things around
There may be other errors that come up with VideoCapture.read that would make a read_attempt method worthwhile, but I could only find the two errors the docs mention. For those it just returns false which the code already tests for.
import os
import threading
import cv2
my_opencv_path = "C:/opencv2.4.3"
video_path_1 = os.path.join(my_opencv_path, "samples", "cpp", "tutorial_code",
"HighGUI", "video-input-psnr-ssim", "video",
"Megamind.avi")
video_path_2 = os.path.join(my_opencv_path, "samples", "c", "tree.avi")
assert os.path.isfile(video_path_1)
assert os.path.isfile(video_path_2)
class MyThread (threading.Thread):
maxRetries = 20
def __init__(self, thread_id, name, video_url, thread_lock):
threading.Thread.__init__(self)
self.thread_id = thread_id
self.name = name
self.video_url = video_url
self.thread_lock = thread_lock
def run(self):
print "Starting " + self.name
window_name = self.name
cv2.namedWindow(window_name)
video = cv2.VideoCapture(self.video_url)
while True:
# self.thread_lock.acquire() # These didn't seem necessary
got_a_frame, image = video.read()
# self.thread_lock.release()
if not got_a_frame: # error on video source or last frame finished
break
cv2.imshow(window_name, image)
key = cv2.waitKey(50)
if key == 27:
break
cv2.destroyWindow(window_name)
print self.name + " Exiting"
def main():
thread_lock = threading.Lock()
thread1 = MyThread(1, "Thread 1", video_path_1, thread_lock)
thread2 = MyThread(2, "Thread 2", video_path_2, thread_lock)
thread1.start()
thread2.start()
print "Exiting Main Thread"
if __name__ == '__main__':
main()
Colenso Castellino
Updated on June 05, 2022Comments
-
Colenso Castellino almost 2 years
I am trying to read to 2 Video Files and show them in separate Windows Simultaneously. This is my code:
import threading import cv2 threadLock=threading.Lock() class myThread (threading.Thread): maxRetries=20 def __init__(self, threadID, name,video_url): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.video_url=video_url def attemptRead(self,cvVideo): threadLock.acquire() (isRead,cvImage)=cvVideo.read() threadLock.release() if isRead==False: count=1 while isRead==False and count<myThread.maxRetries: threadLock.acquire() (isRead,cvImage)=cvVideo.read() threadLock.release() print self.name+' try no: ',count count+=1 return (isRead,cvImage) def run(self): print "Starting " + self.name windowName = self.name cv2.namedWindow(windowName) cvVideo = cv2.VideoCapture(self.video_url) while True: (isRead,cvImage)=self.attemptRead(cvVideo) if isRead==False: break cv2.imshow(windowName,cvImage) key=cv2.waitKey(50) if key==27: break cv2.destroyWindow(windowName) print self.name + "Exiting" def main(): thread1 = myThread(1, "Thread1",'C:/Traffic Pics/Videos/Panjim Capture.mp4') thread2 = myThread(2, "Thread2",'C:/Traffic Pics/Videos/Miramar Capture.mp4') thread1.start() thread2.start() print "Exiting Main Thread" if __name__ == '__main__': main()
What's happening is that, only the Thread 2 Window is showing. Thread 1 exits after attempting to read the video beyond the max_retries limit(10 in my case). The problem is that although I create separate cvVideo objects, I can't seem to use them simultaneously. What could be the problem?
-
Colenso Castellino about 11 yearsThanks for the information about the errors and the extra code. However, the code you provided doesn't work either. As I mentioned in my earlier comments, Multi-threading only seems to work with the tree.avi file in the samples folder. It doesn't work for anything else. Maybe this is just an issue on my system, even so, what could be the reason behind this? Some Codec issues maybe?
-
KobeJohn about 11 yearsPlease check my edit. After installing the codec, everything is fine with Megamind for me.
-
Colenso Castellino about 11 yearsThank you very much! It was a codec problem after all! :D I installed K-lite Mega Codec pack and can now see both the windows opening and playing the videos. Thanks again!