OpenCV

Pywiki
Sam (토론 | 기여)님의 2021년 10월 4일 (월) 15:23 판 (→‎이미지 관련)
둘러보기로 가기 검색하러 가기

1 개요

오픈소스 컴퓨터 비전 라이브러리. 실시간 이미지 프로세싱에 중점을 두었다. 주로 이미지를 읽거나 영상을 읽고 연산을 적용한 후 표시, 다른 파일로 저장하는 용으로 쓰인다.

Numpy에 유일하다시피 의존한다. 기본적으로 이미지를 배열처리.

2 준비

의도 설명 방법
설치 pip install opencv-python

3 기초 사용

의도 설명 방법
임포트 import cv2

3.1 이미지 관련

의도 설명 방법
이미지 읽기 이미지파일을 읽고 창에 띄운다.
읽기모드 설명
cv2.IMREAD_COLOR 컬러(BGR) 스케일로 받는다.(디폴트)
cv2.IMREAD_UNCHANGED 파일 그대로
cv2.IMREAD_GRAYSCALE 흑백으로 읽기
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) # 해당 영상의 초당 프레임 수를 구한다.
속성 설명
cv2.PROP_FRAME_WIDTH 프레임의 폭
cv2.PROP_FRAME_HEIGHT 프레임 높이
cv2.PROP_POS_AVI_RATIO 동영상 파일의 현재 위치(0~1 사이.)

이외 수많은 속성들이 있다.

영상 속성 지정 객체.set 함수를 이용해 속성값을 지정할 수 있다. cap.set(cv2.PROP_FRAME_WIDTH, 320) # 영상의 폭을 320으로 지정.
속성 설명
cv2.PROP_FRAME_WIDTH 프레임의 폭
영상 저장(특정프레임) 특정 프레임을 이미지로 저장.

이미지의 저장과 동일하다.

다음 코드를 적절한 곳에 추가하면 된다.
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 처리 효율

의도 설명 방법
이미지 형태 변환 원본 이미지를 사용하면 처리량이 많아져 계산이 오래걸린다.

옵션은 굉장히 다양한데, 자주 쓰이는 것만 모아보았다.

옵션 설명
cv2.COLOR_BGR2GRAY BGR 컬러 이미지를 그레이스케일로
cv2.COLOR_BGR2RGB BGR을 RGB로 변환
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 함수를 이용하여 매칭할 수 있다.


주의 : 64비트 환경에선 cv2.waitKey() 함수가 아스키코드보다 큰 32비트 정수를 반환하기도 한다. 이를 처리하려면 하위 8비트만 남기고 지운다.

key = cv2.waitKey(10000) & 0xFF  # &연산으로 하위 8비트만 남기고 높은 비트는 0 처리.
if key == ord('a'):  # a키를 받으면...