
Computer Vision이란 정의를 내리긴 힘들지만 대략적으로 다음의 의미를 가진다.
컴퓨터 비전(Computer Vision)은
이미지나 동영상 같은 시각 정보를 컴퓨터가 해석하고 이해할 수 있도록 하는 컴퓨터 분야이다.
즉, 사람의 눈처럼, 컴퓨터가 이미지를 보고 이해하도록 만드는 기술을 의미한다.
CNN이라는 딥러닝 모델은 거의 대부분의 컴퓨터 비전 application에 사용되는 우수한 모델이다. CNN은 이미지 학습을 대상으로 하고 있기 때문에 디지털 이미지에 대해 기본적인 내용을 이해해야 한다.
이미지를 이루는 가장 작은 단위를 pixel이라고 한다.
우리가 모니터의 해상도, 이미지의 해상도라고 말할 때 이 해상도가 바로 pixel의 개수이다.
각 pixel을 밝기값, 혹은 color값을 가지고 있는데 이들이 모여서 이미지 패턴을 만들게 된다.
이때 조심해야 할 사항이 하나 있는데 바로 이미지 처리에서 사용되는 이미지 좌표계(image coordinate)이다.
아래의 그림을 보면 우리가 일반적으로 사용하는 수학의 좌표계(2차원 데카르트 좌표계)와 이미지 처리에서 사용되는 이미지 좌표계(image cooordinate)가 다른 것을 볼 수 있다.

이미지 좌표계는 선형대수의 행렬(Matrix)과 같은 구조이다. M개의 row와 N개의 column을 가지는
M x N Matrix를 가정해봤을 때 M은 이미지의 y축과 매칭되고 N은 이미지의 x축과 매칭된다.
따라서 이미지를 2차원 ndarray로 표현할 때는
pixel[세로, 가로]의 형태가 된다는 것을 조심해야 한다.
디지털 이미지 중 가장 간단한 형태는 이진 이미지(binary image)이다.
각 pixel의 값은 0(어두움) 또는 1(밝음)으로만 표현한다.
언뜻 생각하기에 각 pixel을 표현하기 위해 1 bit만 있으면 되기 때문에 size가 작을 것이라 생각된다.
하지만 실제로는 하나의 pixel을 표현하기 위해 8 bit를 사용하기 때문에 흑백 이미지(gray-scale image)와 크기가 같다. 따라서 많이 사용되지 않는다.
회색조 이미지(gray-scale image)는 각 pixel의 값을 0~255 사이의 값으로 표현한 이미지이다.
각 pixel은 8bit를 사용한다. 부호가 없는 8bit를 사용하기 때문에 0~255 사이의 값을 가질 수 있는 것이다. 많은 영상처리 알고리즘은 용량을 줄이기 위해 회색조 이미지를 대상으로 처리한다는 것도 기억해야 한다.
가장 복잡한 이미지 형태는 당연히 컬러 이미지(color image)이다.
컬러 이미지는 3개의 channel로 표현되며 각 channel은 빛의 3원색인 R(red), G(green), B(blue)의 색상값이다. 0~255의 값을 가지고 있다.
이 3가지 색의 조합으로 다양한 색상을 만들어 내는 것인데 8 * 3 = 24이므로 총 24bit의 색을 표현할 수 있다. 이를 True Color라고 한다. 확장자가 png인 파일은 여기에 투명도인 Alpha channel을 포함시켜서 이미지를 표현한다. 이 경우 RGBA인 32bit 컬러 이미지를 사용하는 것이다.
당연히 컬러 이미지의 크기가 가장 크며, 흑백(회색조) 이미지와 이진 이미지의 크기가 작다. 위에서도 언급했지만 이진 이미지는 1 pixel을 표현할 때 1bit만 있으면 되지만 실제로 8bit를 사용하기 때문에 흑백 이미지와 이진 이미지의 크기는 같다.
우리는 컬러 이미지는 3차원, 회색조 이미지는 2차원으로 생각하는데 사실 모든 이미지는 3차원이다. 즉, 컬러 이미지와 회색조 이미지 모두 3차원으로 표현된다. 이때 회색조 이미지는 RGB의 값이 똑같다. 즉, 컬러 이미지의 각 pixel안에 있는 RGB의 값을 평균내서 RGB 각 값에 평균값을 할당하면 컬러 이미지가 회색조 이미지가 된다.
아래는 컬러 이미지를 회색조 이미지로 각 pixel값의 평균을 사용하여 변경하는 코드이다.
# Pillow Image 객체를 이용해서 간단하게 출력할 수 있다.
plt.imshow(color_img)
plt.show()

# 각 pixel의 RGB 값을 평균을 내서 그 값으로 RGB값을 다시 설정
gray_pixel = color_pixel.copy()
for y in range(gray_pixel.shape[0]):
for x in range(gray_pixel.shape[1]):
gray_pixel[y, x] = int(np.mean(gray_pixel[y, x]))
print(gray_pixel.shape) # (426, 640, 3)
plt.imshow(gray_pixel)
plt.show()
