juuuding

[Computer Vision & Deep Learning] Image Processing - 디지털 영상 기초 본문

인공지능/cs231n

[Computer Vision & Deep Learning] Image Processing - 디지털 영상 기초

jiuuu 2023. 11. 1. 16:34

 영상 획득과 표현

 

 사람의 눈과 마찬가지로 카메라는 물체에서 반사된 빛이 카메라의 작은 구멍에 들어가 뒷면에 있는 영상 평면에 맺히면서 영상을 얻게 되는 것이다. 이 영상 평면은 사람의 경우 망막, 필름 카메라의 경우 필름, 디지털 카메라의 경우 CCD 센서다. 이렇게 얻은 영상은 초기에 아날로그 신호이며, 영상을 메모리 공간에 저장하기 위해서는 아날로그 신호를 디지털 신호로 바꿔주어야 한다.

 디지털 신호로 바꾸기 위해서는 샘플링, 양자화 이 두가지 과정이 필요하다. 먼저 샘플링은 2차원 영상 공간을 가로 N개, 세로 M개로 나눈다. 이렇게 나눠진 공간 중 한 점을 화소(pixel)이라고 하고, MxN을 영상의 크기 또는 해상도라고 한다. 다음으로는 이렇게 샘플링 된 영상을 양자화 해야한다. 양자화는 각 화소들의 명암을 L개의 구간으로 나누는 것이다. 명암을 한 바이트로 표현하기 위해 L을 256으로 설정하는 것이 일반적이다. 

 

영상 획득 과정
샘플링 & 양자화

 

 영상은 2차원 공간의 함수로 간주할 수 있다. 디지털 영상 좌표는 두 가지 측면에서 일반적인 표기와 다르다. 첫 번째는 왼쪽 위가 원점이라는 점이고, 두 번째는 (y,x)표기를 사용한다는 것이다. 행렬에서 행을 먼저 표기하고 열을 표기하는 관행과 같이, 행을 나타내는 y를 먼저 작성하고 열을 나타내는 x를 작성한다. 영상을 저장하는 배열에서 화소의 위치를 저장할 때는 (y,x)를 사용하지만 그 외에는 주로 (x,y)를 이용한다. 예를 들어, 이미지에 직사각형을 그리는 함수를 이용할 때 직사각형의 시작점을 (20,30)으로 설정한다면, 이는 x=20 y=30을 의미하는 것이다. (ex. cv.rectangle(img, (20,30)...)). 참고로 우리가 영상을 처리할 때는 numpy가 지원하는 다양한 함수들을 이용할 수 있다.

 

 

 다양한 종류의 영상

 

 우선 컬러 영상3차원 배열로 표현이 되며, 마지막 차원은 BGR을 표현하는 3개의 채널로 구성된다. 반면 명암 영상은 채널이 한 개이기 때문에 2차원 배열로 표현한다. 웹 캠에서 입력되는 컬러 동영상4차원 배열로 표현하고, 컬러 영상 중 자외선, 적외선 영역까지 확장한 다분광 영상, 초분광 영상, MR, CT3차원 배열로 표현되며 세 번째 축의 크기는 3개보다 더 큰 값으로 확장된다. RGB-D라는 색과 깊이 정보를 표현하는 영상은 3차원 배열에 세 번째 축 크기가 4이다.

 영상의 색은 BGR이 3가지로 표현 가능한데, 세 요소가 모두 0이면 검정, 모두 1이면 하양이다. 세 요소가 같은 값을 갖는 부분은 색상은 없고 명암만 있는 부분이다. HSV이라는 컬러 모델은 Hue(색상), Saturation(채도), Value(명암)을 표현하는 3가지 요소로 구성되어 있다. 따라서 빛의 영향을 덜 받는 프로그램을 제작하고 싶다면 RGB 컬러 모델을 HSV 컬러 모델로 변환하면 좀 더 유리해진다. 3차원 영상을 배열로 표현하여 shape를 확인해보면, img.shape[0]은 y축, img.shape[1]은 x축, img.shape[2]는 BGR로 구성된 z축으로 표현된다. 예를 들어, img[:,:,0], img[:,:,1], img[:,:,2]는 영상의 BGR 채널을 따로 떼어 표시하는 것이다. 

 

 

[컬러 영상을 채널별로 구분해 디스플레이]

  아래의 코드에서는 slicing을 이용하여 영상의 특정 부분만 잘라 보고, 전체 영상에서 BGR 채널을 하나씩 떼서 볼 수 있다. 여기서 주목해야할 점은 BGR 채널을 따로 떼어 봤을 때, 각 채널의 색을 가진 부분이 밝게 표시된다는 것이다. 예를 들면 영상에서 빨간색 부분은 R채널에서 밝게, 그 외의 채널에서는 어둡게 나타난다. 

 

원본
G 채널
R 채널
B 채널

 

[code]

import cv2 as cv
import sys

img=cv.imread("resource/soccer.jpg")
img=cv.resize(img,dsize=(0,0),fx=0.5,fy=0.5)

if img is None:
    sys.exit("파일을 찾을 수 없습니다.")

cv.imshow("original",img)
# 좌측 위
cv.imshow("Upper left half",img[0:img.shape[0]//2,0:img.shape[1]//2,:])
# 가운데
cv.imshow("Center half",img[img.shape[0]//4:img.shape[0]*3//4,img.shape[1]//4:img.shape[1]*3//4,:])

cv.imshow("R channel",img[:,:,2])   # 빨간 부분이 밝음
cv.imshow("G channel",img[:,:,1])   # 초록 부분이 밝음
cv.imshow("B channel",img[:,:,0])   # 파란 부분이 밝음


cv.waitKey()
cv.destroyAllWindows()