ipTIME C300에 대한 개인적인 제품평
심심풀이로 ipTIME사의 C300이라는 홈캠을 구입하게 되었고, 제품이 도착 하자마자 잔뜩 기대를 품고 제품을 개봉하여 바로 설치해 보았다. 자그마한 크기에 손쉬운 설치, 깨끗한 영상에 낮은 조도환경에서도 만족할 만한 감도를 보여줄 뿐만이 아니라 Pan/Tilt 기능도 지원하여 꽤나 만족스러운 기능과 성능을 보이는 제품이었다. 단점을 꼽자면, 30FPS에 한참 못 미치는 6FPS의 초당 전송속도와 더불어 가장 크게 실망한 부분은 ONVIF 표준을 지원하지 않는다는 점이었다. 즉, 내가 스스로 코딩하여 내가 원하는 모든 기능을 수행해 주는, 나만의 프로그램을 만들수 없다는 부분이었다. (물론, 지금의 나는 그러한 프로그램을 만들 수 있는 능력이 되지 않는 것이 사실이지만 말이다.)
그렇지만, 다행스러운 부분도 있었다. 즉, ONVIF 표준은 활용할 수 없지만 RTSP 기능은 지원하고 있는 것을 확인한 것이다.
비디오 디스플레이, 이미지 저장, 비디오 녹화를 수행하는 간단한 프로그램
일전에 USB 카메라로 부터 읽어온 영상을 디스플레이하고, 한장의 이미지를 저장하고, 영상을 녹화할 수 있는 짧은 프로그램을 작성해 보았다. 이 내용을 담고 있는 이전 글을 참고 하시려는 분들은 “OpenCV를 이용하여 비디오 저장/녹화하기 [Python]“을 참고해 주셨으면 한다.
ipTIME C300으로 부터 영상을 얻어 디스플레이하고, 이미지를 저장하고, 비디오를 녹화하는 프로그램도 기본적으로 이전에 작성한 USB 카메라를 이용한 코딩과 전혀 다르지 않다. 다만, USB가 아닌 네트워크를 통해서 비디오를 얻어오는 부분을 수정하고, 1초당 디스플레이하는 이미지 갯수를 영상에 오버레이하여 출력해 주는 부분만 약간 수정 되었다.
작성한 코딩
ipTIME C300에서 RTSP를 이용하여 비디오를 얻어오는 구문은 “rtsp://IP_Address:554” 이다. 이 접속정보를 적용하여 위 기능들을 구현한 전체 코드 내용은 아래와 같다.
import cv2 import time cap = cv2.VideoCapture('rtsp://id:password@192.168.1.21:554') cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) bRec = False prevTime = 0 while True: ch = cv2.waitKey(167) ret, frame = cap.read() curTime = time.time() sec = curTime - prevTime prevTime = curTime fps = 1 / (sec) str = " FPS : %0.1f" % fps cv2.putText(frame, str, (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0)) cv2.imshow('VideoFrame', frame) if ch == ord('s'): # s 버튼이 눌리면 cv2.imwrite('image.jpg', frame) if ch == ord('r'): # r 버튼이 눌리면 if not bRec: outputVideo = cv2.VideoWriter('Video.avi', cv2.VideoWriter_fourcc(*'DIVX'), 6.0, (2288, 1288)) bRec = True else: outputVideo.release() if bRec: outputVideo.write(frame) bRec = False if ch == ord('q'): # q 버튼이 눌리면 break cap.release() cv2.destroyAllWindows()
코딩에 대한 간락한 설명
cap = cv2.VideoCapture('rtsp://id:password@192.168.1.21:554')
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
비디오 캡처 객체인 cap을 생성하고, 비디오는 ipTIME C300의 “rtsp://IP주소:rtsp 포트번호”로 부터 받아온다.
비디오의 가로폭과 세로폭은 1280 x 720으로 지정한다.
while True:
ch = cv2.waitKey(167)
ret, frame = cap.read()
cv2.imshow('VideoFrame', frame)
167ms 간격으로 cap 객체로 부터 비디오를 읽어서, 그 이미지를 디스플레이 한다.
curTime = time.time()
sec = curTime - prevTime
prevTime = curTime
fps = 1 / (sec)
str = " FPS : %0.1f" % fps
cv2.putText(frame, str, (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0))
현재 시간(curTime)을 읽어서 이전 시간(prevTime)에 저장한다.
현재 시간과 이전 시간의 시간차(sec)를 이용해서 초당 프레임수 (FPS, Frame Per Second)를 계산한다.
계산된 FPS를 (0, 100) 위치에 폰트크기 1, 녹색으로 비디오에 Overlay 해서 출력한다.
(주) ipTIME C300의 초당 프레임수는 대략 6FPS으로 확인 되었다. 즉, 약 167ms (=1000ms / 6FPS) 간격으로 비디오를 전달 받기 때문에 이 값을 ch = cv2.waitKey(167)에 활용 되었다.
if ch == ord('s'): # s 버튼이 눌리면
cv2.imwrite('image.jpg', frame)
키보드의 ‘s’ 버튼이 눌리면, 현재의 영상 프레임 한장을 ‘image.jpg’라는 이름으로 저장한다.
if ch == ord('r'): # r 버튼이 눌리면
if not bRec:
outputVideo = cv2.VideoWriter('Video.avi',
cv2.VideoWriter_fourcc(*'DIVX'),
6.0, (2288, 1288))
bRec = True
else:
outputVideo.release()
키보드의 ‘r’ 버튼이 눌리고, 아직 녹화가 시작되지 않은 상태라면 (if not bRec), VideoWriter 객체인 outputVideo를 생성하고, bRec을 True로 변경한다. 만약 bRec = True인 상태에서 키보드의 ‘r’ 버튼이 눌리면, outputVideo를 릴리즈 한다.
outputvideo의 속성은 아래와 같다.
- ‘Video.avi’라는 이름으로 비디오 파일 생성
- 비디오 파일은 DivX로 압축
- 초당 6장(Frame)의 이미지를 저장
- 비디오 사이즈는 2288 x 1288 (ipTIME C300이 지원하는 비디오 해상도)
if bRec:
outputVideo.write(frame)
bRec = False
167ms 간격으로 bRec 상태를 체크하고 bRec = True인 상태라면, 비디오 프레임을 outputVideo 인스턴스에 저장한다.
if ch == ord('q'): # q 버튼이 눌리면
break
cap.release()
cv2.destroyAllWindows()
키보드의 ‘q’ 버튼이 눌리면, VideoCapture 객체의 인스턴스 cap을 해제하고, 프로그램을 종료한다.
마무리 하며
비록 ipTIME사의 C300이 ONVIF를 지원하고 있지는 않지만, 가성비 측면에서는 꽤나 구매를 권장하고 싶은 제품이 틀림없다. 다만, ONVIF 공부를 염두해 둔 분들이라면, 홈캠을 구입하기 전에 ONVIF 지원여부와 더불어 CMOS 센서의 해상도, 초당 전송속도(FPS), Pan/Tilt 기능의 지원여부를 반드시 확인해 보고 구매를 결정하기를 권장 드린다.