이미지 다루기

Goal

  • 이미지 파일을 읽고, 보고, 저장하는 방법에 대해서 알아봅니다.

  • 관련 함수인 cv2.imread(), cv2.imshow(), cv2.imwrite() 에 대해서 알아 봅니다.

이미지 읽기

우선 openCV모듈을 import합니다.:

>>> import cv2

cv2.imread() 함수를 이용하여 이미지 파일을 읽습니다. 이미지 파일의 경로는 절대/상대경로가 가능합니다.

>>> img = cv2.imread('lena.jpg', cv2.IMREAD_COLOR)
cv2.imread(fileName, flag)

이미지 파일을 flag값에 따라서 읽어들입니다.

Parameters
  • fileName (str) – 이미지파일의 경로

  • flag (int) – 이미지 파일을 읽을 때의 Option.

Returns

image객체 행렬

Return type

numpy.ndarray

이미지 읽기의 flag는 3가지가 있습니다.

  • cv2.IMREAD_COLOR : 이미지 파일을 Color로 읽어들입니다. 투명한 부분은 무시되며, Default값입니다.

  • cv2.IMREAD_GRAYSCALE : 이미지를 Grayscale로 읽어 들입니다. 실제 이미지 처리시 중간단계로 많이 사용합니다.

  • cv2.IMREAD_UNCHANGED : 이미지파일을 alpha channel까지 포함하여 읽어 들입니다.

Note

3개의 flag대신에 1, 0, -1을 사용해도 됩니다.

img값은 numpy의 ndarray type입니다. numpy는 python에서 수학적 처리를 위한 모듈로 openCV에서도 많이 사용됩니다. img가 어떤 형태의 행렬인지 확인을 해보려면 아래와 같이 입력합니다.

>>> img.shape
(206, 207, 3)

이미지는 3차원 행렬로 return이 됩니다. 206은 행(Y축), 207은 열(X축), 3은 행과 열이 만나는 지점의 값이 몇개의 원소로 이루어져 있는지를 나타납니다. 위 값의 의미는 이미지의 사이즈는 207 X 206이라는 의미입니다.

그렇다면 3은 어떤 의미일까요. 바로 색을 표현하는 BGR값입니다. 일반적으로 RGB로 많이 나타내는데, openCV는 B(lue), G(reen), R(ed)로 표현을 합니다.

Alpha channel을 포함하는 이미지(보통 png 파일)를 cv2.IMREAD_UNCHANGED 로 읽는 경우 마지막이 4로 표시됩니다. 알파채널만 따로 떼어 출력을 해보면 투명한 부분이 전부 검은색으로 보이는데, 이러한 특성 때문에 마스크 채널이라고도 불립니다.

>>> cv2.imshow('alpha',img[:,:,3])

다음은 읽은 이미지를 보는 방법에 대해서 알아보겠습니다.

이미지 보기

cv2.imshow() 함수는 이미지를 사이즈에 맞게 보여줍니다.

>>> c22.imshow('image', img)
>>> cv2.waitKey(0)
>>> cv2.destroyAllWindows()
cv2.imshow(title, image)

읽어들인 이미지 파일을 윈도우창에 보여줍니다.

Parameters
  • title (str) – 윈도우 창의 Title

  • image (numpy.ndarray) – cv2.imread() 의 return값

cv2.waitKey() 는 keyboard입력을 대기하는 함수로 0이면 key입력까지 무한대기이며 특정 시간동안 대기하려면 milisecond값을 넣어주면 됩니다.

cv2.destroyAllWindows() 는 화면에 나타난 윈도우를 종료합니다. 일반적으로 위 3개는 같이 사용됩니다.

Sample Code

 1import cv2
 2
 3fname = 'lena.jpg'
 4
 5original = cv2.imread(fname, cv2.IMREAD_COLOR)
 6gray = cv2.imread(fname, cv2.IMREAD_GRAYSCALE)
 7unchange = cv2.imread(fname, cv2.IMREAD_UNCHANGED)
 8
 9cv2.imshow('Original', original)
10cv2.imshow('Gray', gray)
11cv2.imshow('Unchange', unchange)
12
13cv2.waitKey(0)
14cv2.destroyAllWindows()
../../_images/lena.jpg

Sample Image

아래는 각 flag에 따른 이미지 결과입니다.

../../_images/1.jpg

Original

../../_images/2.jpg

Grayscale

../../_images/3.jpg

Unchange

이미지 저장하기

cv2.imwrite() 함수를 이용하여 변환된 이미지나 동영상의 특정 프레임을 저장합니다.

>>> cv2.imwrite('lenagray.png', gray)
cv2.imwrite(fileName, image)

image파일을 저장합니다.

Parameters
  • fileName (str) – 저장될 파일명

  • image – 저장할 이미지

Sample Code

이미지를 읽어서 esc키를 누르면 종료, ‘s’ key를 누르면 grayscale이미지가 저장이 되는 Sample입니다. cv2.waitKey() 사용을 잘 보시기 바랍니다.:

import cv2

img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k == 27: # esc key
    cv2.destroyAllWindow()
elif k = ord('s'): # 's' key
    cv2.imwrite('lenagray.png',img)
    cv2.destroyAllWindow()

Warning

64bit OS의 경우 k = cv2.waitKey(0) & 0xFF로 bit연산을 수행해야 합니다.

Matplotlib 사용하기

Matplotlib는 다양한 plot기능을 가진 Python Plot Library입니다. 이미지를 zoom하거나 하나의 화면에 여러개의 이미지를 보고자 할 때 유용합니다.

Sample Code

 1#-*- coding:utf-8 -*-
 2import cv2
 3from matplotlib import pyplot as plt # as는 alias 적용시 사용
 4
 5img = cv2.imread('lena.jpg', cv2.IMREAD_COLOR)
 6
 7plt.imshow(img)
 8plt.xticks([]) # x축 눈금
 9plt.yticks([]) # y축 눈금
10plt.show()

Result

../../_images/4.jpg

Matplotlib Result

그런데 결과가 좀 이상합니다. 원본은 붉은색 계열인데, 결과는 파란색 계열로 나타납니다.

이유는 openCV는 BGR로 사용하지만, Matplotlib는 RGB로 이미지를 보여주기 때문입니다.

즉 결과 값은 3차원 배열의 값중 첫번째와 세번째 배열값을 서로 바꿔 주여야 합니다.

그럼 변경된 Sample을 보시기 바랍니다.

Sample Code

 1#-*- coding:utf-8 -*-
 2import cv2
 3from matplotlib import pyplot as plt # as는 alias 적용시 사용
 4
 5img = cv2.imread('lena.jpg', cv2.IMREAD_COLOR)
 6img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 7
 8plt.axis('off') # 창의 x축 y축 제거
 9plt.imshow(img2)
10plt.show()

Result

../../_images/5.jpg

RGB값으로 변경한 결과