OpenCV
둘러보기로 가기
검색하러 가기
1 개요
오픈소스 컴퓨터 비전 라이브러리. 실시간 이미지 프로세싱에 중점을 두었다. 주로 이미지를 읽거나 영상을 읽고 연산을 적용한 후 표시, 다른 파일로 저장하는 용으로 쓰인다.
Numpy에 유일하다시피 의존한다. 기본적으로 이미지를 배열처리.
2 준비
의도 | 설명 | 방법 |
---|---|---|
설치 | pip install opencv-python | |
3 기초 사용
의도 | 설명 | 방법 |
---|---|---|
임포트 | import cv2 | |
3.1 이미지 관련
의도 | 설명 | 방법 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
이미지 읽기 | 이미지파일을 읽고 창에 띄운다.
|
img = cv2.imread('이미지 경로', 읽기모드)
cv2.imshow('창이름', img) # 창이름을 가진 창에 이미지를 띄운다.
cv2.waitKey(0) # 아무 키가 입력될 때까지 대기. 이미지를 띄울 때 이게 없으면 바로 끝난다. 눌린 키에 대응하여 값을 반환한다.
cv2.destroyAllWindows() # 모든 창 닫기.
| ||||||||
이미지 저장 | 처리 후 다시 저장하기 위해. | cv2.imwrite('저장경로', img) # 파일 포멧까지 지정해주어야 한다.
|
3.2 영상 관련
의도 | 설명 | 방법 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
영상 불러오기 | VideoCapture의 인수로 0을 주면 웹캠을 열고,
인수로 영상파일 경로를 주면 파일을 열어 분석한다. |
cap = cv2.VideoCapture(0) # 경로가 아닌 숫자라면, 카메라 번호를 의미한다.
while True:
ret, img = cap.read() # read로 프레임을 하나씩 읽는다.
if not ret: # ret엔 cap.isOpened() 가 담겨 영상이 열려있는지 여부를 반환한다.
break
# 프레임 하나하나 이미지 처리되어 img 객체에 담기니, 이를 처리하면 된다.
cv2.imshow('창이름', img) # 창을 열어 보여준다. 프레임마다 빠르게 불러 영상처럼.
if cv2.waitKey(1) != -1: # 아무 키가 입력될 때까지 ms단위로 대기. 파일에 따라 다른 값을 준다. 너무 빠르게 넘어가면 볼 수가 없어.
break # 아무 키가 입력되면 멈춘다. 아무 키가 없으면 -1 반환.
cap.release() # 객체에서 사용하던 자원을 반납한다.
cv2.destroyAllWindows()
| ||||||||
영상 내보내기 | 처리한 영상을 img에 담으면 각 프레임마다
'창이름'이라는 창을 띄워 매끄러운 영상으로 보여준다. |
cv2.imshow('창이름', img)
cv2.waitKey(1) # 이게 있어야 창이 제대로 열린다.
| ||||||||
영상 속성 보기 | 객체.get 함수를 이용하면 볼 수 있다. | cap.get(cv2.CAP_PROP_FPS) # 해당 영상의 초당 프레임 수를 구한다.
이외 수많은 속성들이 있다. | ||||||||
영상 속성 지정 | 객체.set 함수를 이용해 속성값을 지정할 수 있다. | cap.set(cv2.PROP_FRAME_WIDTH, 320) # 영상의 폭을 320으로 지정.
| ||||||||
영상 저장(특정프레임) | 특정 프레임을 이미지로 저장.
이미지의 저장과 동일하다. |
다음 코드를 적절한 곳에 추가하면 된다.if cv2.waitKey(1) != -1: # 아무 키가 입력될 때까지 ms단위로 대기.
cv2.imwrite('사진경로.jpg', img) # 해당 이미지를 저장한다.
| ||||||||
영상 저장(특정구간) | 특정 구간을 영상으로 저장.
적절한 fourcc값은 링크에서 찾아보자. |
# 사전 인수 설정.
file_path = '주소.avi'
fourcc = cv2.VideoWriter_fourcc(*'DIVX') # 비디오인코딩 형식(4글자)
# 비디오 저장 클래스 객체를 생성한다.
writer = cv2.VideoWriter(file_path, fourcc,
fps, # 초당 프레임
(width, height) # 크기
)
while True:
ret, img = cap.read()
...
writer.write(img) # 해당 프레임을 쓴다.
if cv2.waitKey(1) != -1: # 아무 키가 입력될 때까지 ms단위로 대기.
break # 키를 누르면 녹화를 멈춘다.
writer.release() # 파일을 닫는다.(자원 반환)
|
3.2.1 팁
너무 고화질의 영상이라면 픽셀 수가 많아 연산하는 데 오래걸린다. 때문에 프레임 폭, 높이 조절로 픽셀 수를 줄이는 편이 이득.
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
[카메라 외의 영상은 이렇게 안줄여진다고 하던데...]
3.2.2 처리 효율
의도 | 설명 | 방법 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
이미지 형태 변환 | 원본 이미지를 사용하면 처리량이 많아져 계산이 오래걸린다.
옵션은 굉장히 다양한데, 자주 쓰이는 것만 모아보았다.
|
cov_img = cv2.cvtColor(img, cv2.COLOR_옵션) # 원본 img와 옵션을 받아 형태를 변환한다.
| ||||||||
바이너리 | 이미지를 검은색과 흰색만으로 표현한 것.
그레이스케일보다 더 빠른 처리를 위해서 + 피사체의 모양을 더 명확하게 파악하기 위해. |
ret, cov_img = cv2.threshold(img, 경계값, 255, cv2.THRESH_BINARY)
# ret엔 트레시홀딩에 사용한 경계값이 나오니, 버리는 값이다.
ret, cov_img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # 원본 img와 옵션을 받아 형태를 변환한다.
# ret에 사용된 경계값이 담기니, 이 ret은 쓸만할지도..
오츠의 알고리즘을 사용하면 모든 경우의 수에 대한 경계값을 조사하기 때문에 느리다. |
4 꾸미기
4.1 글씨 쓰기
의도 | 설명 | 방법 |
---|---|---|
글씨쓰기 | 영상이나 이미지에 글씨를 쓴다. | cv2.putText(img, # 글씨를 표시할 이미지나 프레임.
text, # 표시할 텍스트.
point, # 표시할 좌표. 문자열의 좌측 하단이 기준이 된다.
fontFace, # 글씨체
fontSize, # 1이 평범한 크기.
color, # (255,255,255) 형태.
)
|
5 외부입력
의도 | 설명 | 방법 |
---|---|---|
키 입력 받기 | cv2.waitKey(ms) 함수는 특정 시간동안 키입력이 없으면 -1을 반환한다.
인수로 0을 주면 무한정 기다린다. 반환하는 키 코드는 아스키코드와 같아 ord 함수를 이용하여 매칭할 수 있다.
|
key = cv2.waitKey(10000) & 0xFF # &연산으로 하위 8비트만 남기고 높은 비트는 0 처리.
if key == ord('a'): # a키를 받으면...
|