ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OpenCV] Webcam 2개 연결 시, No space left on device 에러가 날 때
    Tech/Development 2013. 10. 10. 00:18

    Stereo Matching 등을 하기 위해 카메라를 2개 연결해서 사용할 때가 있는데, 만약 라즈베리파이 등 자그마한(!) 임베디드 보드에서 구현한다면 다음과 같은 에러를 만날 수도 있다.

    libv4l2: error tuning on stream: No space left on device
    VIDIOC_STREAMON: No space left on device

    이러한 에러가 발생하는 이유는 Webcam의 resolution, framerate, protocol을 USB 2.0으로 전송하기에는 너무 느리기 때문이다! 요즘 USB 3.0이 지원되기 시작하지만 아직까지 USB Webcam은 대부분 2.0 기반이며, 이러한 Webcam은 USB 3.0 포트에 연결하더라도 2.0으로 동작하게 된다. 640x480 크기의 영상이 30 frame/second로 들어올 때 최소 211 Mbit/s 이상의 bandwidth가 필요하게 되는데, USB 2.0의 effective throughput이 280 Mbit/s 이라는 점을 생각해보면 Webcam 2개로부터 들어오는 정보(211*2=422 Mbit/s)를 처리하기에는 턱없이 부족하다는 것을 알 수 있다.

    서로 다른 USB host에 Webcam을 연결해서 해결하기

    가장 손쉬운 해결 방법은 각 Webcam을 연결할 때, 서로 다른 USB host를 사용하는 것이다. lsusb 명령어를 이용해서 어느 bus에 webcam이 연결되었는지 확인할 수 있다. 그런데 PC의 경우는 대부분 여러 개의 USB host를 가지고 있기 때문에 위와 같은 USB 대역폭 문제를 아예 겪어보지 못했을 수도 있으나, 임베디드 보드의 경우에는 USB host를 여러 개 Webcam에 연결해 쓸 만큼 넉넉하지 않을 수 있다.

    OpenCV의 V4L (Video for Linux) 관련 라이브러리 수정해서 해결하기

    OpenCV의 소스코드 자체를 바꿔서 해결할 수 있다. USB webcam을 통해 전달받는 영상 데이터의 빈도(framerate)를 줄여서 대역폭을 감소시킬 수 있다. 기본적으로는 실시간 30 framerate로 설정되어있는 부분을 적당히 바꾸면 된다. OpenCV source code 폴더로 들어가서, ./modules/highgui/src/cap_libv4l.cpp을 찾아서 열어보자. 아래 부분을 찾아서 원하는 framerate로 변경한 뒤, 다시 컴파일해서 설치하면 된다.

    /* try to set framerate to 30 fps */
    struct v4l2_streamparm setfps;
    memset (&setfps, 0, sizeof(struct v4l2_streamparm));
    setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    setfps.parm.capture.timeperframe.numerator = 1;
    setfps.parm.capture.timeperframe.denominator = 30;
    xioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps);
    

    댓글

Copyright 2022 JY