본문 바로가기

머신러닝,딥러닝/opencv

opencv 입문하기 2편 - 이미지 객체 속성 , 픽셀값 변경

이번 시간에는 opencv에서 이미지를 부를 때의 객체 속성과 픽셀 접근에 대해 코딩 및 설명 해보겠습니다. 

 

opencv 에서 이미지를 부르면 보통 BGR 순서로 부릅니다.

저희가 보는 컬러 이미지는 보통 RGB 순서입니다. 그러므로 순서의 변환이 필요합니다. 

또한, opnecv 는 영상 데이터를 numpy.ndarray 로 표현합니다. 

 

numpy.ndarray 의 특징을 opencv 의 영상 관점에서 보면 

 

ndim: 차원 

shape 

- (h,w) : grayscale 영상 - 흑백 영상

- (h,w, 3) : 컬러 영상 

size: 전체 픽셀 갯수

dtype: 원소의 데이터 타입 uint8

 

으로 이해하면 됩니다. 

 

 

우선, 예제 영상 결과를 보고나서 코드로 설명하겠습니다. 

 

 

 

제가 최초에 가져온 이미지는 위 사진 중에서 가운데 있는 사진입니다. 

헌데 opencv 에서 그냥 imread 로 부르면 좌측의 이미지처럼 됩니다. BGR 순서로 되어있기 때문입니다. 

cvtColor 를 이용해서 BGR 로 불려온 이미지를 RGB 로 바꿔줍니다. 

 

cv2Color 함수의 설명은 

 

Converts an image from one color space to another. (한 색 공간에서 다른 색 공간으로 이미지 변환)

 

The function converts an input image from one color space to another.(이 함수는 입력 이미지를 한 색 공간에서 다른 색 공간으로 변환한다.) In case of a transformation to-from RGB color space, the order of the channels should be specified explicitly (RGB or BGR). Note that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the bytes are reversed).(OpenCV의 기본 색상 형식을 RGB라고 하는 경우가 많지만 실제로는 BGR(바이트가 역행됨)이라는 점에 유의하세요.)

So the first byte in a standard (24-bit) color image will be an 8-bit Blue component, the second byte will be Green, and the third byte will be Red. The fourth, fifth, and sixth bytes would then be the second pixel (Blue, then Green, then Red), and so on.

 

The conventional ranges for R, G, and B channel values are:

  • 0 to 255 for CV_8U images
  • 0 to 65535 for CV_16U images
  • 0 to 1 for CV_32F images

공식 문서에서 가져온 설명입니다. 

중요하다 싶은 부분만 번역했습니다 :) 

 

 

import matplotlib.pyplot as plt
import cv2

# opencv 는 image 가 BGR 로 되어있음.

imgBGR = cv2.imread('서예지님2.jpg')
imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB)
imgGRAY = cv2.imread('서예지님2.jpg', cv2.IMREAD_GRAYSCALE)

cv2.imshow('imgBGR', imgBGR)
cv2.imshow('imgRGB', imgRGB)
cv2.imshow('imgGRAY', imgGRAY)

cv2.moveWindow('imgBGR', 200, 200)
cv2.moveWindow('imgRGB', 600, 200)
cv2.moveWindow('imgGRAY', 1000, 200)

cv2.waitKey()
cv2.destroyAllWindows()

 

 

 

근데 위 이미지는 실제 이미지 사이즈들로 나와서 좀 크게 나옵니다. 

그래서 matplotlib 으로 이미지를 보겠습니다. 

아래 결과처럼 나오게요! 

 

 

 

 

코드는 아래와 같습니다. 

matplotlib 설명은 생략할게요 :)

 

import matplotlib.pyplot as plt
import cv2

# opencv 는 image 가 BGR 로 되어있음.

imgBGR = cv2.imread('서예지님2.jpg')
imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB)
imgGRAY = cv2.imread('서예지님2.jpg', cv2.IMREAD_GRAYSCALE)

# matplotlib 들을 이용해서 이미지들을 한창에서 보기
plt.subplot(131), plt.axis('off'), plt.imshow(imgBGR)
plt.subplot(132), plt.axis('off'), plt.imshow(imgRGB)
plt.subplot(133), plt.axis('off'), plt.imshow(imgGRAY, cmap='gray')
plt.show()

 

 

그리고 앞에서 말한 영상의 shape, size, dtype 을 확인해보겠습니다. 

이미지를 부르면 실제로는 numpy.ndarray 라고 했는데요.

실제로 확인해보겠습니다.

 

 

 

 

 

 

ndarray 이고 그레이스케일링 한 이미지는 2차원, 컬러 이미지는 3차원으로 나오네요. 

size 는 픽셀이라고 가로세로 곱이라고 했습니다. 

각각의 2차원, 3차원 이미지들을 곱한 값들이 size 로 나옵니다. (계산기로 640*640, 640*640*3 하면 확인가능해요~)

dtype 은 uint8 로 나오네요.  이 얘기는 범위가 0~255 라는 것입니다.

2^8 = 256 이니깐요.

 

 

+) 픽셀값 변경 

 

이제 특정 부위 픽셀값들의 값을 변경해볼게요.

그러면 색상이 변경되겠죠? 

 

 

 

이미지 좌측 상단에서 파란색으로 바뀐 게 보이나요? 

특정 픽셀의 값들을 이중 for 문을 써서 값을 (255,0,0) 으로 채우니깐 파란색으로 됐습니다. 

dtype 이 uint8 이기에 넣을 수 있는 차원들의 범위는 0~255 까지 입니다. 

 

 

이것으로 포스팅 마치겠습니다 :) 

 

 

 

 

참고

 

https://docs.opencv.org/master/d8/d01/group__imgproc__color__conversions.html#ga397ae87e1288a81d2363b61574eb8cab

 

OpenCV: Color Space Conversions

enum  cv::ColorConversionCodes {   cv::COLOR_BGR2BGRA = 0,   cv::COLOR_RGB2RGBA = COLOR_BGR2BGRA,   cv::COLOR_BGRA2BGR = 1,   cv::COLOR_RGBA2RGB = COLOR_BGRA2BGR,   cv::COLOR_BGR2RGBA = 2,   cv::COLOR_RGB2BGRA = COLOR_BGR2RGBA,   cv::COLOR_R

docs.opencv.org