코딩. 캠핑

OpenCV Python 입문(4) - 영상의 속성과 픽셀 값 참조 본문

Dev(개발)/OpenCV(Python)

OpenCV Python 입문(4) - 영상의 속성과 픽셀 값 참조

진영_8 2021. 1. 28. 13:43

OpenCV 는 영상 데이터를 numpy.ndarray로 표현한다.

numpy.ndarray

  • ndim : 차원 수. len(img.shape)와 같음.
  • shape : 각 차원의 크기. (h.w) -그레이스케일 또는 (h, w, 3) -컬러
  • size : 전체 원소 개수
  • dtype : 원소의 데이터 타입. 영상 데이터는 uint8

OpenCV 영상 데이터 자료형과 NumPy 자료형

OpenCV 자료형(1채널) NumPy 자료형 구분
cv2.CV_8U numpy.uint8 8비트 부호없는 정수
cv2.CV_8S numpy.int8 8비트 부호있는 정수
cv2.CV_16U numpy.uint16 16비트 부호없는 정수
cv2.CV_16S numpy.int16 16비트 부호있는 정수
cv2.CV_32S numpy.int32 32비트 부호있는 정수
cv2.CV_32F numpy.float32 32비트 부동소수형
cv2.CV_64F numpy.float64 64비트 부동소수형
cv2.CV_16F numpy.float16 16비트 부동소수형

그레이스케일 영상 : cv2.CV_8UC1 -> numpy.uint8, shape = (h, w)
컬러 영상 : cv2.CV_8UC3 -> numpy.uint8, shpae = (h, w, 3)


코드를 통해서 영상을 속성을 어떤식으로 참조할 수 있는지 보자.

영상의 속성 참조

import sys
import cv2


# 영상 불러오기
img1 = cv2.imread('cat.bmp', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('cat.bmp', cv2.IMREAD_COLOR)

if img1 is None or img2 is None:
    print('이미지를 불러오는데 실패했습니다!')
    sys.exit()

# 영상의 속성 참조
print(type(img1))
print(img1.shape)
print(img2.shape)
print(img1.dtype)
print(img2.dtype)

 

실행을 해보면 위와 같은 결과를 얻을 수 있다.
img1은 2차원, img2는 3차원으로, dtype이 각각 uint8로 잡히는 걸 볼 수 있다.

불러온 영상이 그레이스케일인지, 컬러영상인지 확인하려면 

if img1.ndim == 2 :
    print("img1은 그레이스케일 이미지 입니다.") 
elif img1.ndim == 3 :
    print("img1는 컬러 이미지 입니다.")

라고 쓰거나 아래처럼 써도 무방하다.

if len(img1.shape) == 2 :
    print("img1은 그레이스케일 이미지 입니다.") 
elif len(img1.shape) == 3 :
    print("img1는 컬러 이미지 입니다.")

 

 그리고 영상의 가로 세로 크기를 뽑아내고 싶다면 아래와 같이 쓰면 된다.

# 영상의 크기 참조
h, w = img1.shape
print('img1 shape = w x h = {} x {}'.format(w, h))
h, w = img2.shape[:2]
print('img2 shape = w x h = {} x {}'.format(w, h))

img2에 [:2]를 해주는 이유는 컬러 이미지 shape 에는 가로 세로 말고도 차원 수가 적혀있기 때문이다.


픽셀 값의 참조

예를 들어서 (20,10) 좌표에 있는 픽셀값을 찾고 싶다고 해보자.

x = 20
y = 10
p1 = img1[y,x]
print('img1 = ', p1)

p2 = img2[y,x]
print('img2 = ', p2)

img1은 그레이스케일이라 해당 좌표의 밝기 값인 238이 나오고,
img2는 컬러영상이라 Blue, Green, Red 순서로 해당 값이 나온다.

반대로, 해당 좌표에 픽셀값을 직접 지정해줄 수도 있다.

x = 20
y = 10

img1[y, x] = 0
img2[y, x] = (0, 0, 255)

cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.waitKey()

cv2.destroyAllWindows()

각 창 왼쪽 위에 정말 작은 점 하나씩 보이십니까...?

한 픽셀만 넣어놓은거기 때문에 잘 안보이니까 좀 더 보기 쉽게 하기 위해 코드를 조금 손보겠다.

h, w = img1.shape
h, w = img2.shape[:2]

for y in range(h):
    for x in range(w):
        img1[y, x] = 0
        img2[y, x] = (0, 255, 255) # 노란색

cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.waitKey()

cv2.destroyAllWindows()

비록 고양이는 사라졌지만, 모든 픽셀이 바뀐걸 볼 수 있다.
이런 방식으로 좌표의 픽셀값을 참조하고 그 위치에 값을 써 넣을 수 있다는걸 알 수 있다.
하지만, 이런 작업은 되도록 안하는게 좋다. 엄청 느리기 때문이다.

가급적이면 numpy나 OpenCV에서 제공하는 것들로 세팅하는것이 좋다.

 

 

 

Comments