2017-06-15 406 views
1

我有两个摄像头(使用OpenNI,每个摄像头有两个流,由相同的驱动程序API实例处理),并且想要两个线程,每个线程捕获数据从每个摄像机独立,即驱动程序API的一个实例,说cam_handler,我有两个流depthrgb每台摄像机,说cam_handler.RGB1_streamcam_handler.DEPTH1_streamPython中的多线程cv2.imshow()不起作用

下面是相同的代码:

import threading 

def capture_and_save(cam_handle, cam_id, dir_to_write, log_writer, rgb_stream, 
        depth_stream, io): 
    t = threading.currentThread() 
    shot_idx = 0 
    rgb_window = 'RGB' + str(cam_id) 
    depth_window = 'DEPTH' + str(cam_id) 
    while getattr(t, "do_run", True): 
     if rgb_stream is not None: 

      rgb_array = cam_handle.get_rgb(rgb_stream) 
      rgb_array_disp = cv2.cvtColor(rgb_array, cv2.COLOR_BGR2RGB) 
      cv2.imshow(rgb_window, rgb_array_disp) 
      cam_handle.save_frame('rgb', rgb_array, shot_idx, dir_to_write + str(cam_id + 1)) 
      io.write_log(log_writer[cam_id], shot_idx, None) 

     if depth_stream is not None: 
      depth_array = cam_handle.get_depth(depth_stream) 
      depth_array_disp = ((depth_array/10000.) * 255).astype(np.uint8) 
      cv2.imshow(depth_window, np.uint8(depth_array_disp)) 
      cam_handle.save_frame('depth', depth_array, shot_idx, dir_to_write + str(cam_id + 1)) 
     shot_idx = shot_idx + 1 

     key = cv2.waitKey(1) 
     if key == 27: # exit on ESC 
      break 
    print "Stopping camera %d thread..." % (cam_id + 1) 
    return 

def main(): 
    ''' Setup camera threads ''' 
    cam_threads = [] 
    dir_to_write = "some/save/path" 
    for cam in range(cam_count): 
     cam = (cam + 1) % cam_count 
     cv2.namedWindow('RGB' + str(cam)) 
     cv2.namedWindow('DEPTH' + str(cam)) 
     one_thread = threading.Thread(target=capture_and_save, 
             name="CamThread" + str(cam + 1), 
             args=(cam_cap, cam, dir_to_write, 
              log_writer, 
              rgb_stream[cam], depth_stream[cam], io,)) 
     cam_threads.append(one_thread) 
     one_thread.daemon = True 
     one_thread.start() 

     try: 
      while True: 
       pass 
       # cv2.waitKey(1) 
     except KeyboardInterrupt: 
      ''' Stop everything ''' 
      for each_thread in cam_threads: 
       each_thread.do_run = False 
       each_thread.join(1) 
      cam_cap.stop_rgb(rgb_stream) 
      cam_cap.stop_depth(depth_stream) 

      ''' Stop and quit ''' 
      openni2.unload() 
      cv2.destroyAllWindows() 

if __name__ == '__main__': 
    main()  

所以,我的问题是,如果我删除cv2.imshow()代码中的所有行都按预期运行,我将两个摄像头输出保存到文件。但是,使用cv2.imshow()行时,只会创建“空白”窗口,并且线程似乎“卡住”,根本没有输出。
我尝试了几个建议,包括将namedWindow创建移动到主线程以及capture_and_save线程。我也尝试在waitKey()之间移动,因为据说OpenCV只允许在主线程中使用waitKey()。然而,没有区别。

回答

0

我解决了这个问题,通过使用mutables,将字典cam_disp = {}传递给线程并读取主线程中的值。当保存在主线程中时cv2.imshow()的效果最好,所以这工作得很好。我不确定这是否是“正确”的方式来做到这一点,所以我们欢迎所有的建议。

+0

请你发布修改后的代码为好,我刚刚撞我的头,因为最近5小 – csharpcoder

+0

@csharpcoder看看https://github.com/kanishkaganguly/OpenNIMultiSensorCapture/blob/master/capture_cam.py 我认为这是最新的代码,有上面提到的变化。 –

+0

我的不好,我只是承诺最新的工作代码。 https://github.com/kanishkaganguly/OpenNIMultiSensorCapture/blob/master/capture_tool.py –