복붙노트

[PYTHON] 한 번에 OpenCV에서 두 카메라의 비디오 캡처

PYTHON

한 번에 OpenCV에서 두 카메라의 비디오 캡처

Python API를 사용하여 OpenCV를 사용하여 한 번에 (또는 거의) 둘 이상의 카메라에서 비디오를 어떻게 캡처합니까?

나는 / dev / video0, / dev / video1 및 / dev / video2에있는 세 개의 웹캠을 가지고 있습니다. 모두 비디오 스트리밍이 가능합니다.

튜토리얼을 예로 들면, 단일 카메라에서 이미지를 캡처하는 것은 간단합니다.

import cv2
cap0 = cv2.VideoCapture(0)
ret0, frame0 = cap0.read()
cv2.imshow('frame', frame0)
cv2.waitKey()

그리고 이것은 잘 작동합니다.

그러나 두 번째 카메라를 초기화하려고 시도하면 두 번째 카메라에서 read ()를 시도하면 None이 반환됩니다.

import cv2
cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
ret0, frame0 = cap0.read()
assert ret0 # succeeds
ret1, frame1 = cap1.read()
assert ret1 # fails?!

실수로 OpenCV에 불량 카메라 인덱스를 제공하지 않도록 각 카메라 인덱스를 개별적으로 테스트했으며 모두 자체적으로 작동합니다. 예 :

import cv2
#cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
#ret0, frame0 = cap0.read()
#assert ret0
ret1, frame1 = cap1.read()
assert ret1 # now it works?!

내가 뭘 잘못하고 있죠?

편집 : 내 하드웨어 Ubuntu를 실행하는 맥북 프로입니다. 특히 맥북에 관한 이슈를 조사한 결과, OSX와 다른 유형의 카메라 모두에서이 문제를 겪은 다른 사람들을 발견했습니다. iSight에 액세스하면 코드에서 두 호출이 모두 실패합니다.

해결법

  1. ==============================

    1.네, 확실히 USB 대역폭에 의해 제한됩니다. 전체 장치에서 두 장치를 모두 읽으려고하면 오류가 발생합니다.

    네, 확실히 USB 대역폭에 의해 제한됩니다. 전체 장치에서 두 장치를 모두 읽으려고하면 오류가 발생합니다.

    libv4l2: error turning on stream: No space left on device
    VIDIOC_STREAMON: No space left on device
    Traceback (most recent call last):
      File "p.py", line 7, in <module>
        assert ret1 # fails?!
    AssertionError
    

    그리고 나서 해상도를 160x120로 줄이면 :

    import cv2
    cap0 = cv2.VideoCapture(0)
    cap0.set(3,160)
    cap0.set(4,120)
    cap1 = cv2.VideoCapture(1)
    cap1.set(3,160)
    cap1.set(4,120)
    ret0, frame0 = cap0.read()
    assert ret0 # succeeds
    ret1, frame1 = cap1.read()
    assert ret1 # fails?!
    

    지금 그것은 작동하는 것처럼 보인다! 두 캠을 같은 USB 카드에 연결했으면 좋겠어. lsusb 명령을 실행하여 다음과 같이 표시해야합니다.

    Bus 001 Device 006: ID 046d:081b Logitech, Inc. Webcam C310
    Bus 001 Device 004: ID 0409:005a NEC Corp. HighSpeed Hub
    Bus 001 Device 007: ID 046d:0990 Logitech, Inc. QuickCam Pro 9000
    Bus 001 Device 005: ID 0409:005a NEC Corp. HighSpeed Hub
    Bus 001 Device 003: ID 0409:005a NEC Corp. HighSpeed Hub
    Bus 001 Device 002: ID 1058:0401 Western Digital Technologies, Inc. 
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    

    (두 대의 카메라가 같은 버스에 있음을주의하십시오.) 가능한 경우 다른 USB 카드를 기기에 추가하여 더 많은 대역폭을 확보 할 수 있습니다. 전 한 대의 컴퓨터에서 최대 해상도로 여러 개의 카메라를 실행하기 전에이 작업을 수행했습니다. 사용 가능한 마더 보드 슬롯이있는 타워 워크 스테이션 이었지만 불행히도 MacBook 랩톱에는 그러한 옵션이 없을 수 있습니다.

  2. ==============================

    2.OPENCV와 2 개의 표준 USB 카메라를 사용하여 멀티 스레딩을 사용하여이 작업을 수행 할 수있었습니다. 기본적으로 opencv 윈도우와 VideoCapture 요소를 여는 하나의 함수를 정의하십시오. 그런 다음 카메라 ID와 창 이름을 입력으로하여 두 개의 스레드를 만듭니다.

    OPENCV와 2 개의 표준 USB 카메라를 사용하여 멀티 스레딩을 사용하여이 작업을 수행 할 수있었습니다. 기본적으로 opencv 윈도우와 VideoCapture 요소를 여는 하나의 함수를 정의하십시오. 그런 다음 카메라 ID와 창 이름을 입력으로하여 두 개의 스레드를 만듭니다.

    import cv2
    import threading
    
    class camThread(threading.Thread):
        def __init__(self, previewName, camID):
            threading.Thread.__init__(self)
            self.previewName = previewName
            self.camID = camID
        def run(self):
            print "Starting " + self.previewName
            camPreview(self.previewName, self.camID)
    
    def camPreview(previewName, camID):
        cv2.namedWindow(previewName)
        cam = cv2.VideoCapture(camID)
        if cam.isOpened():  # try to get the first frame
            rval, frame = cam.read()
        else:
            rval = False
    
        while rval:
            cv2.imshow(previewName, frame)
            rval, frame = cam.read()
            key = cv2.waitKey(20)
            if key == 27:  # exit on ESC
                break
        cv2.destroyWindow(previewName)
    
    # Create two threads as follows
    thread1 = camThread("Camera 1", 1)
    thread2 = camThread("Camera 2", 2)
    thread1.start()
    thread2.start()
    

    파이썬에서 스레드하는 법을 배우는 훌륭한 자료 : https://www.tutorialspoint.com/python/python_multithreading.htm

  3. ==============================

    3.나는 "imutils"를 사용하고 이미지에서 웹캠 쇼를 읽습니다.

    나는 "imutils"를 사용하고 이미지에서 웹캠 쇼를 읽습니다.

    비디오 프레임 캡처

    read_frame () 함수를 만들어 Image.fromarray에 대한 매개 변수를 보내고 표시합니다.

    최종 기능은 "imageFrame"에 비디오를 보여줍니다.

    예. 4 웹캠

    유튜브 : 유튜브

  4. ==============================

    4.이것은 오랫동안 저에게 고통이었습니다. 그래서 OpenCV 위에 라이브러리를 만들어 여러 카메라와 뷰포트를 처리했습니다. 나는 기본적으로 압축하지 않는 비디오 나 메인 스레드에서만 표시되는 윈도우와 같은 많은 문제를 겪었습니다. 지금까지 Windows에서 두 개의 720p 웹캠을 실시간으로 표시 할 수 있습니다.

    이것은 오랫동안 저에게 고통이었습니다. 그래서 OpenCV 위에 라이브러리를 만들어 여러 카메라와 뷰포트를 처리했습니다. 나는 기본적으로 압축하지 않는 비디오 나 메인 스레드에서만 표시되는 윈도우와 같은 많은 문제를 겪었습니다. 지금까지 Windows에서 두 개의 720p 웹캠을 실시간으로 표시 할 수 있습니다.

    시험:

    pip install CVPubSubs
    

    그럼, 파이썬에서 :

    import cvpubsubs.webcam_pub as w
    from cvpubsubs.window_sub import SubscriberWindows
    
    t1 = w.VideoHandlerThread(0)
    t2 = w.VideoHandlerThread(1)
    
    t1.start()
    t2.start()
    
    SubscriberWindows(window_names=['cammy', 'cammy2'],
                  video_sources=[0,1]
                  ).loop()
    
    t1.join()
    t1.join()
    

    비교적 새로운 것이므로, 버그 나 최적화되지 않은 코드에 대해 알려주십시오.

  5. ==============================

    5.이 코드를 사용해보십시오 ... 그것은 예상대로 작동 ... 당신이 더 많은 카메라를 원하면 "VideoCapture ()"객체를 만드십시오 ... 예를 들어 세 번째 캠은 다음을 갖습니다 : cv2.VideoCapture (3) 및 while 루프의 해당 코드

    이 코드를 사용해보십시오 ... 그것은 예상대로 작동 ... 당신이 더 많은 카메라를 원하면 "VideoCapture ()"객체를 만드십시오 ... 예를 들어 세 번째 캠은 다음을 갖습니다 : cv2.VideoCapture (3) 및 while 루프의 해당 코드

    import cv2
    
    frame0 = cv2.VideoCapture(1)
    frame1 = cv2.VideoCapture(2)
    while 1:
    
       ret0, img0 = frame0.read()
       ret1, img00 = frame1.read()
       img1 = cv2.resize(img0,(360,240))
       img2 = cv2.resize(img00,(360,240))
       if (frame0):
           cv2.imshow('img1',img1)
       if (frame1):
           cv2.imshow('img2',img2)
    
       k = cv2.waitKey(30) & 0xff
       if k == 27:
          break
    
    frame0.release()
    frame1.release()
    cv2.destroyAllWindows()
    

    모든 최고!

  6. from https://stackoverflow.com/questions/29664399/capturing-video-from-two-cameras-in-opencv-at-once by cc-by-sa and MIT license