2017-06-15 405 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 –