개요
Python
언어로 컴퓨터 비전 관련 프로그램을 작성할 때 다양한 영상 소스가 사용되고, 우리가 일반적으로 웹캠이라 부르는 USB 단자를 통해 연결되는 UVC 카메라가 상당히 많이 사용된다.
다양한 제조사에서 만드는 카메라들은 다양한 해상도를 지원하고 밝기, 채도, 색상 등 다양한 조절할 수 있는 프로퍼티가 많다. 하지만 이를 어떻게 조정하는지 잘 모르는 사람도 있고 구체적으로 어떻게 조정해야할 지 모르는 경우도 많아서 이에 대해 작성해 보고자 한다.
환경
아래에 기술할 방법론은 윈도우기반 os에서 확인이 불가능한 것은 아니지만 리눅스기반 os환경에선 쉽게 확인할 수 있다. 아래의 내용에선 Ubuntu
OS를 전제로 서술한다.
v4l2-ctl
설치
우선 터미널에서 v4l2-ctl
명령어를 통해 연결된 카메라의 제어가능한 프로퍼티을 확인할 수 있다. v4l2-ctl
명령어가 없다면 터미널에서 아래의 명령어를 통해 설치한다.
$ sudo apt install v4l-utils
카메라 확인
설치가 완료되었다면 일단 아래의 명령어를 통해서 연결되어있고 사용가능한 카메라 목록을 볼 수 있다.
$ v4l2-ctl --list-devices
결과는 다음과 같이 나온다.
C270 HD WEBCAM (usb-0000:00:14.0-10.2):
/dev/video0
/dev/video1
HD USB Camera: HD USB Camera (usb-0000:00:14.0-10.4):
/dev/video2
/dev/video3
본인의 경우 로지텍의 C270카메라가 /dev/video0
, /dev/video1
장치명을 할당, 개발환경을 위한 또 다른 USB 카메라가 /dev/video2
, /dev/video3
을 할당하는 것을 볼 수 있다.
카메라 프로퍼티 확인
지원해상도
v4l2-ctl
명령어와 장치명을 알려주는 -d
옵션 그리고 지원해상도를 보기위한 --list-formats-ext
옵션을 같이 사용하여 카메라가 지원하는 해상도와 프레임레이트를 알 수 있다. 명령어는 아래와 같다.
$ v4l2-ctl -d /dev/video0 --list-formats-ext
결과는 다음과 같이 나왔다.
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
...
...
...
Size: Discrete 1024x576
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1184x656
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
...
...
...
Size: Discrete 1024x576
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1184x656
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
지원하는 해상도가 너무나 다양하므로 중간에 출력된 결과는 일부 생략하였다. 위의 결과를 보면 해당 /dev/video0
카메라의 지원하는 해상도는 160*120
부터 1280*960
까지 확인된다. 또한 각 해상도에 따른 프레임레이트도 확인된다. YUYV
는 영상의 비디오 데이터 형식(format)이며 YUV420
, YUV422
등 색상공간을 나타내는 방법이 다양한데 여기서 설명은 굳이 하지 않는다. 영상의 원시 출력정도로 이해하면 된다. MJPG
는 이에 비해 압축 알고리즘을 적용하여 픽셀을 표현한다. MJPG
포맷이 제공하는 프레임레이트(FPS)는 어느정도 고해상도로 올라가면 YUYV
의 것보다 높음을 알 수 있다. 예를 들면 YUYV
의 1280*720
해상도에서는 선택할 수 있는 FPS가 5
, 7,5
인 반면에 MJPG
로 선택하면 최대 30FPS
까지 지원된다.
세부 프로퍼티
다시 해당 카메라의 프로퍼티를 보기 위해 v4l2-ctl
명령어와 디바이스를 지정하는 -d
옵션, 그리고 프로퍼티를 보기위한 --all
옵션을 사용한다. 아래의 명령어를 참조하여 실행한다.
$ v4l2-ctl -d /dev/video0 --all
결과는 아래와 같다.
Driver Info:
Driver name : uvcvideo
Card type : C270 HD WEBCAM
Bus info : usb-0000:00:14.0-10.2
Driver version : 5.15.131
Capabilities : 0x84a00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format
Priority: 2
Video input : 0 (Input 1: ok)
Format Video Capture:
Width/Height : 640/480
Pixel Format : 'YUYV' (YUYV 4:2:2)
Field : None
Bytes per Line : 1280
Size Image : 614400
Colorspace : sRGB
Transfer Function : Rec. 709
YCbCr/HSV Encoding: ITU-R 601
Quantization : Default (maps to Limited Range)
Flags :
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 640, Height 480
Default : Left 0, Top 0, Width 640, Height 480
Pixel Aspect: 1/1
Selection Video Capture: crop_default, Left 0, Top 0, Width 640, Height 480, Flags:
Selection Video Capture: crop_bounds, Left 0, Top 0, Width 640, Height 480, Flags:
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 30.000 (30/1)
Read buffers : 0
User Controls
brightness 0x00980900 (int) : min=0 max=255 step=1 default=128 value=128
contrast 0x00980901 (int) : min=0 max=255 step=1 default=32 value=32
saturation 0x00980902 (int) : min=0 max=255 step=1 default=32 value=32
white_balance_automatic 0x0098090c (bool) : default=1 value=1
gain 0x00980913 (int) : min=0 max=255 step=1 default=0 value=8
power_line_frequency 0x00980918 (menu) : min=0 max=2 default=2 value=2
0: Disabled
1: 50 Hz
2: 60 Hz
white_balance_temperature 0x0098091a (int) : min=0 max=10000 step=10 default=4000 value=0 flags=inactive
sharpness 0x0098091b (int) : min=0 max=255 step=1 default=24 value=24
backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=1 value=1
Camera Controls
auto_exposure 0x009a0901 (menu) : min=0 max=3 default=3 value=3
1: Manual Mode
3: Aperture Priority Mode
exposure_time_absolute 0x009a0902 (int) : min=1 max=10000 step=1 default=156 value=156 flags=inactive
exposure_dynamic_framerate 0x009a0903 (bool) : default=0 value=1
중간 쯤의 User Controls
출력 결과를 보면 다양한 프로퍼티들이 있는데 이들이 컨트롤 가능한 프로퍼티 들이다. 굳이 변경하지 않아도 카메라를 사용하는데 문제는 없지만 본인이 사용할 장비에서 무엇을 통제할 수 있는가를 아는 것은 중요하다. 위의 예시에서는 조절 가능한 프로퍼티는 아래 내용 등과 같다.
- 밝기(brightness): 최솟값-0, 최댓값-255, 기본값-128, 현재값-128
- 대조(contrast): 최솟값-0, 최댓값-255, 기본값-32, 현재값-32
- 채도(saturation): 최솟값-0, 최댓값-255, 기본값-32, 현재값-32\
- 게인(gain): 최솟값-0, 최댓값-255, 기본값-0, 현재값-8
- 화이트밸런스 자동설정: 기본값-1, 현재값-1
- 화이트밸런스(white_balance_temperature): 최솟값-0, 최댓값-10000, 기본값-4000, 현재값-0(자동설정이라 그렇다)
또한 Camera Controls
항목을 보면 카메라의 노출도 조정할 수 있는 것으로 보인다 기본은 자동노출로 되어있지만 이를 수동으로 바꾸면 카메라 프로퍼티 중 노출(exposure)에 대한 값을 조절할 수 있다.
Opencv-python
Property
위에서 알아본 프로퍼티들을 python
의 opencv
라이브러리에서 cv2.Videocapture
클래스를 통해 제어한다. 비디오캡처라고 부르는 인스턴스를 통해 해당 클래스가 제공하는 메소드 중 set()
과 get()
메소드를 통해 프로퍼티 값을 조회하고 설정할 수 있다. 이를 통제하기 위해선 opencv
모듈이 제공하는 카메라 프로퍼티의 상수값을 알아야한다. 이는 다음 링크(opencv-videoio flag)를 통해 확인 가능하다. 아래의 이미지만 참고해도 상당히 많은 것을 알 수 있다.
Control
아래의 코드를 참고하여 프로퍼티 값을 조회하고 설정한다.
아래의 예시는 카메라 해상도를 조회하고 설정하는 예시다. 특히 해상도를 그냥 올리면 YUYV
포맷이 유지되어 프레임레이트(FPS)가 낮게 설정되는 경우가 있으니 주의하자. 본인이 지정한 FPS가 YUYV
에서도 지원한다면 문제없지만 지원하지 않는다면 명시적으로 데이터 포맷을 MJPG
로 바꿔줘야한다.
get()
import cv2 cap = cv2.VideoCapture('/dev/video0') w = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # cap.get(3) h = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # cap.get(4) print(w, h)
640 480
위의
cv2.CAP_PROP_FRAME_WIDTH
등의 프로퍼티는 상수 값이기 때문의 아래의3
,4
등의 정수로 입력해도 동작은 동일하다. 이어서 카메라의 기본 해상도가640*480
으로 확인되었고1280*720
으로 올려준뒤 FPS를 확인해본다.set()
import cv2 cap = cv2.VideoCapture('/dev/video0') cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) fps = cap.get(cv2.CAP_PROP_FPS) # cap.get(5) print(fps)
7.5
1280*720
해상도의YUYV
포맷은 7.5fps가 기본값이다. 이를MJPG
포맷의 30FPS로 바꿔주기 위해 아래와 같이 다시 작업한다.import cv2 cap = cv2.VideoCapture('/dev/video0') vid_fmt = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') cap.set(cv2.CAP_PROP_FOURCC, vid_fmt) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) cap.set(cv2.CAP_PROP_FPS, 30) fps = cap.get(cv2.CAP_PROP_FPS) # cap.get(5) print(fps)
30
위와 같이 작성하면 프레임레이트(FPS)가
30
이 나오는 것을 확인할 수 있다.cap.set(cv2.CAP_PROP_FPS, 30)
구문을 명시안해줘도 될 수도 있지만 해당 C270카메라의 경우 직접 명시하지 않으면 FPS 기본값이 15로 설정되어있으니 가급적이면 명시를 습관적으로 하는것이 좋다.
해상도나 FPS 뿐 아니라 위에서 알아본 채도, 밝기, 감마 등의 값도 조절 가능하다. 기본값의 사용이 문제가 없다면 일반적으로 변경할 일이 없지만 기본 카메라가 너무 밝다던지, 혹은 카메라 노출을 자동에서 수동으로 변경하여 밝기를 고정한다던지 할 때 유용하게 사용할 수 있다.
아래는 밝기(brightness)를 최소인 0과 최대인 255로 조절해본 결과 이미지의 차이다.
import cv2
cap = cv2.VideoCapture('/dev/video0')
cap.set(cv2.CAP_PROP_BRIGHTNESS, 0)
print(cap.get(cv2.CAP_PROP_BRIGHTNESS))
for _ in range(30):
cap.grab()
ret, frame = cap.read()
cv2.imshow('low_brightness', frame)
cv2.waitKey(0)
cap.set(cv2.CAP_PROP_BRIGHTNESS, 255)
print(cap.get(cv2.CAP_PROP_BRIGHTNESS))
for _ in range(30):
cap.grab()
ret, frame = cap.read()
cv2.imshow('high_brightness', frame)
cv2.waitKey(0)
0
255
중간의 for
구문과 cap.grab()
은 카메라의 파라미터를 변경 후 1초 정도 변경값이 적용될 수 있는 시간 여유를 준 것 이라고 이해하면 된다. 적용된 값을 확인하였고 이미지를 출력해본 결과는 다음과 같다.
다른 파라미터들도 동일하게 적용해보고 확인해 볼 수 있으니 사용자의 필요에 맞게 사용하면 된다.
댓글남기기