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?
*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?
The code you wrote basically works for me. For you and anyone else that wants to try, I did the following:
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()