본문 바로가기

프로그래밍 강좌/파이썬 - OpenCV

[OpenCV][파이썬] 영상 처리 기초 - image 읽기 쓰기 저장 imread VSCode 화소 접근 imshow numpy 리스트 list 튜플 tuple

블로그를 보시면 알겠지만, 저는 c++ 기반의 프로그램을 계속 해 왔습니다. 왜냐하면 회사에서는 파이썬 보다는 c++을 많이 사용하기 때문입니다.

그래도 교육용이나 실시간성이 많이 필요하지 않은 분야에는 파이썬이 많이 적용되고 있기 때문에 저도 파이썬을 이용하여 OpenCV를 한번 강의를 연재해 보려고 합니다.

 

지난 시간에 우리는 Visual Studio Code를 설치하고 OpenCV를 연동해보는 것까지 해 봤습니다.

https://blog.naver.com/dorergiverny/223169168476

 

[OpenCV][파이썬] VSCode 설치 및 anaconda 연동하기 - Visual Studio Code 세팅 IDE 아나콘다 python 최신버전 환

지난번에는 anaconda를 설치하고 Jupyter Notebook을 사용하는 방법에 대해 알아봤습니다. https://m.blo...

blog.naver.com

 

이번에는 본격적인 OpenCV의 세계로 들어가겠습니다.

Visual Studio Code를 열어서 진행하겠습니다.

 

(1) 영상 읽기

일단 OpenCV 패키지를 사용하기 때문에 import cv2를 해 줍니다.

그리고 cv2.imread( '파일 경로/파일명', 1) 으로 영상을 읽어옵니다.

두번째 인자는 아래와 같은 값을 가지고 있습니다.

  • cv2.IMREAD_UNCHANGED or -1 : 영상 파일 변형 없이 원본 그대로
  • cv2.IMREAD_COLOR or 1: BGR 색으로 읽기
  • cv2.IMREAD_GRAYSCALE or 0: 회색으로 읽기

그외에도 많은 옵션이 있으나 위 3가지를 가장 많이 사용합니다.

 

cv2.imread()로 읽어올 수 있는 파일 종류는 아래와 같습니다.

*.png, *.bmp, *.jpeg, *.jpg, *.exr, *.hdr, *.tiff, *.tif 등 왠만한 영상 포맷은 거의 읽어올 수 있습니다.

그리고 type() 이란 명령어를 이용하여 읽어온 image라는 변수의 type을 알아보겠습니다.

numpy.ndarray 라고 합니다. 즉, numpy 패키지의 ndarray type으로 영상을 처리하겠다는 뜻 입니다. numpy 의 배열로 선언이 되었다면 이전에 배웠던 numpy 명령어들을 사용할 수 있습니다.

https://blog.naver.com/dorergiverny/223144197435

 

[데이터 분석][Python] 넘파이 numpy 파이썬 라이브러리 패키지 총정리 배열 난수 생성 shuffle choice

지난번 까지는 파이썬의 기본 문법들에 대해 알아봤습니다. https://m.blog.naver.com/dorergiverny/223136...

blog.naver.com

그럼 읽어온 배열의 shape도 알아볼 수 있습니다.

을 해보면 아래와 같이 나옵니다.

영상 사이즈가 512 x 512 이고 3차원 배열이네요.

3채널 컬러 영상은 아래와 같은 배열 형태를 띄고 있으며, Grayscale 영상은 아래 오른쪽과 같이 단일 차원의 2차원 배열 형태로 구성 되어 있습니다.

그럼 image 객체가 가질 수 있는 메소드에는 어떤 것들이 있는지 알고 싶으면 어떻게 할까요? dir 을 사용하면 됩니다.

dir 을 프린트해보니까 아래와 같이 사용할 수 있는 멤버 함수들이 있음을 알 수 있습니다.

저희는 고작 shape 하나만 사용해봤죠.

(2) 영상을 읽고 display 하기

이번에는 imread 함수의 두번째 인자에 영상을 GrayScale로 읽어오라는 옵션을 추가해보겠습니다.

sys 패키지는 기본 모듈로 별도의 설치가 필요없으며, 시스템 변수를 설정하거나 exit 함수로 프로그램을 종료하는데 사용합니다.

imread() 로 영상을 읽어온 후 if image is None: 이면(영상이 없으면) 프로그램을 종료하는 루틴을 넣어 줬습니다.

imshow("window 이름", 영상객체명) 첫번째 인자 윈도우 이름을 넣고 두번째 인자 영상 객체를 넣어주면 그 영상을 display를 해 줍니다.

waitKey() 는 키보드의 키가 눌릴 때까지 기다리다가 키가 눌리면 해당 키의 유니코드 값을 반환합니다. 아무 숫자를 넣지 않거나 0을 넣으면 무한정 기다리게 됩니다. 시간을 지정하려면 ms 단위로 정수 값을 입력 합니다. 예를 들어 waitKey(1000) 을 넣으면 1초를 기다리게 됩니다. 만약 waitKey()를 넣지 않으면 윈도우가 생성되었다가 바로 소멸되므로 생성되지 않는 것처럼 보이기 때문에 waitKey()를 넣는 것을 습관화 해야 합니다.

destroyAllWindows()는 모든 윈도우를 닫고 프로그램을 끝내는 역할을 합니다.

빈 영상을 만들고 싶을 때에는 numpy 를 사용합니다.

0 값으로 채우되, 사이즈는 높이 480, 넓이 640 으로 하고 채널 수는 3채널 또는 1채널로, 정밀도는 uint8로 만들라는 의미 입니다.

 
OpenCV 형식
데이터 형식
의미
np.uint8
byte
8-bit unsigned integer
np.int8
sbyte
8-bit signed integer
np.uint16
uint16
16-bit unsigned integer
np.int16
int16
16-bit signed integer
np.float32
float
32-bit floating point number
np.double
double
64-bit floating point number

 

(3) 영상 값 접근

영상 값을 읽어 오는 방법에 대해 알아보겠습니다. 컬러 영상일 경우 index로 [0, 1] 픽셀의 bgr 값을 읽어오거나 직접 channel을 지정해서 하나의 값으로 읽어올 수도 있습니다.

gray 영상일 경우도 마찬가지겠죠?

이렇게 읽어 오면 됩니다.

그럼 그 위치에 값을 적어보겠습니다.

이번에는 레나 영상을 color로 그대로 읽어 보도록 하겠습니다. IMREAD_UNCHANGED 옵션을 사용하였습니다.

그리고 for in 문을 사용하여 1~299까지 위치에 빨간 색을 칠해보도록 하겠습니다.

이렇게 수행하게 되면, 아래와 같이 화소에 접근해서 직접 색을 칠할 수 있습니다.

(4) OpenCV에서 사용되는 기본 데이터 타입

(4-1) 리스트(list)

리스트는 파이썬에서 가장 많이 사용되는 자료형으로 대괄호를 이용하여 표현합니다. 리스트는 아래와 같은 3가지 특성을 가지고 있습니다.

 

a. 데이터 종류와 무관하게 값을 저장할 수 있다.

b. 리스트의 값 생성, 추가, 삭제, 변경이 가능하다.

c. 순서가 있다. 즉 indexing, slicing이 가능하다.

 

OpenCV에서 많이 사용하는 리스트의 예 입니다.

입력된 영상을 Binarization을 하는데, 3가지 방법으로 해보는 예제 입니다. method 변수에 list로 방법을 넣은 후 img 배열을 생성합니다. None 값이 저장된 method 길이 만큼 img 배열을 생성하여 for 문을 돌려 각 방법으로 이진화를 수행합니다. 그리고 그 배열의 0번째, 1번째, 2번째 영상을 차례로 imshow를 하는 예제 입니다.

(4-2) 튜플(tuple)

튜플은 소괄호를 이용하여 표현하며, 리스트와 특성이 거의 같으며, 차이점은 '값을 변경할 수 없다' 입니다.

아래와 같이 영상에 원을 그릴 때 tuple을 사용합니다.

circle 함수의 center를 tuple 형식으로 전달하지 않으면 에러가 발생하니 주의하시기 바랍니다.

(4-3) 딕셔너리(dictionary)

딕셔너리는 키(key)와 값(value)으로 구성된 자료형입니다. 중괄호 콜론으로 선언을 하며, 리스트와 특성이 유사하지만 순서가 없고 대신 mapping이 가능하다는 장점이 있습니다. 즉 순서를 고려하지 않고 키를 통해 값을 불러오는 형태입니다.