본문 바로가기
AI/컴퓨터 비전

OpenCV 정리_Grayscale, Color, Matplotlib, NumPy 활용법

by 바다의 공간 2025. 3. 12.

▶프로젝트 환경은 코랩으로 진행! 하려고 했으나 cv2.imshow()는 지원하지 않기때문에 불가했다.

결론은 pycharm으로 진행함!

 


▶ Open CV 

영상을 처리하는 모듈이다. 그래서 따로 설치를 해야한다. 

아래에서 설명하는건 Opencv로 할 수 있는것들을 따로 정리해볼 겸 정리하려고 한다!

 

1. Grayscale

import cv2

#그레이스케일 변환
img1 = cv2.imread('D:\PJ\DLHJ\dog.bmp', cv2.IMREAD_GRAYSCALE)
print(img1)

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

 

그레이스케일은 가장 많이 사용하는 범위가 넓다. 보통 컬러로 이미지처리연산을 하는것보다는 

그레이스케일로 연산하는것이 좀 더 연산량도 적고 빠르기때문이다.

 

한 이미지를 넣으면 이미지로 바로 변환이 되는것이 아니라 행렬이 반환되는데, 이 행렬은 영상에 있는 밝기 정보다.

 

이런식으로 0에서 255까지 숫자로 밝기 표시가 되어있다. 

*참고로 0은 BLACK 255는 WHITE이다*

 

영상을 화면에 띄우기 위해서는 

cv2.imshow()를 해야되는데 안에 파라미터는 아래와 같다.

창의 이름과 실제 파일의 이름을 써야한다.

 

 

그 다음 실행을 누르면 걍 사라진다. waitKey()라는 메서드를 써야한다. 내가 x를 누를때까지 기다리는 메서드다.

 

2. 트루컬러 영상

#트루컬러
img2 = cv2.imread('D:\PJ\DLHJ\dog.bmp', cv2.IMREAD_COLOR)

 

 

여기서 cv2.IMREAD_COLOR는 기본 값이기때문에 안써줘도 된다는점이 포인트다.

즉  img2 = cv2.imread('경로')만 작성해서 cv2.imshow() 하고 cv2.waitKey()를 해도 

똑같이 컬러창이 뜬다는것이다.

 


 

▶ matplotlib

import cv2
import matplotlib.pyplot as plt

혹시나 밑줄이 생긴다면 모듈이 설치되지않은것이기때문에 설치를 해주어야한다.

똑같이 opencv-python을 install하는것 처럼 터미널 창에 pip install matplotlib을 해주면 설치가 완료된다.

 

또 똑같이 GRAY, COLOR을 가져왔습니다.

img_gray = cv2.imread('D:\PJ\DLHJ\dog.bmp', cv2.IMREAD_GRAYSCALE)
img_color = cv2.imread('D:\PJ\DLHJ\dog.bmp') #BGR

 

그치만 여기서 OpenCV는 좀 특이한 부분이 있는데, 바로 컬러를 가져올때 보통과 같이 RGB로 가져오는것이 아니라 BGR로 가져온다는 점입니다.

 

위 사진처럼 plt.subplot(121)로 해도되고 plt.subplot(1,2,1)로 해도 됩니다.

import cv2
import matplotlib.pyplot as plt

img_gray = cv2.imread('D:\PJ\DLHJ\dog.bmp', cv2.IMREAD_GRAYSCALE)
img_color = cv2.imread('D:\PJ\DLHJ\dog.bmp') #BGR

plt.subplot(121)
plt.axis('off')
plt.imshow(img_gray, cmap='gray')

plt.subplot(122)
plt.axis('off')
plt.imshow(img_color)

plt.show()

 

이렇게 하면 아래처럼 사진이 나오게 됩니다.

이유는 뭐냐면 RGB가 아니라 BGR의 형태로 되어있기 때문입니다. 

색 채널이 섞여서 이상하게 된거예요. 그래서 OPENCV에서는 BGR로 가져오기때문에 항상 

 

이 둘의 차이점은 뭘까요? 방금 위에서 했을때는 같은 사진임에도 불구하고 컬러로 잘 나왔는데 

방금같은 서브플랏은 파랑색으로 나오는 이상한 형태가 되는데 이유가 뭘까요!!!!

 

바로 위에는 cv2.로 받아왔기때문에 이미지가 변환되지않았지만, 바로 위는 matlotlib으로 받아왔기때문에

이미지 변환이 생긴것입니다.

 

그러면 어떻게 해야할지 생각을 해보자면, 컬러이미지를 RGB로 변경을 해주어야하는데 

변경해주는 함수는 cv2.COLOR_BGR2RGB입니다.

 

img_color = cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)

 

짠 이렇게 해서 matplotlib에서도 변경해주어서 이미지까지 잘 넣어주었습니다.

 


▶ Image Type (이미지 타입 알아보기)

 

-Grayscale

import cv2

img_gray = cv2.imread('D:\PJ\DLHJ\dog.bmp', cv2.IMREAD_GRAYSCALE)
print('img_gray type', type(img_gray))

 

>>img_gray type <class 'numpy.ndarray'>

 

그레이스케일로 불러왔을대는, 넘파이의 엔디어레이로 있습니다.

아까 밝기정보를 행렬로 받아온것에 대해서 이제 연결이 되죠?

print('img_gray shape', img_gray.shape)

다음 shpae를 가져와보니(364, 548) 입니다.

근데 지금 보니가 가로보다 세로가 더 길게 나오는 수치입니다.

위에서 보면 분명 가로가 더 길고 세로가 더 짧은 형태인데 이 부분도 이상하죠?

 

그래서 정리를 하자면

Opencv의 색상은 'BGR'이다

Opencv의 길이는 '세로-가로' 라는점을 알고있어야합니다.

print('img_gray shape', img_gray.dtype) #uint8

 

uint8가나오는데, U는 un을 의미하고 int는 정수를 의미합니다 그래서 즉 -가 없는 숫자를 의미하고 

8은 2의 8제곱 해서 256이 됩니다. 그래서 아주 알찬 데이터타입 이라는 점이라는것도 기억해야겠습니다.


-Color type

img_color = cv2.imread('D:\PJ\DLHJ\dog.bmp')
print('img_color type', type(img_color))
print('img_color shape', img_color.shape) #세로, 가로, 색상
print('img_color shape', img_color.dtype) #uint8

img_color type <class 'numpy.ndarray'>
img_color shape (364, 548, 3)
img_color shape uint8

 

이렇게 나오는데 shape가 좀 확실히 다른점이 느껴집니다.

컬러기때문에 3이 붙은것을 알 수 있습니다. 그래서 길이는 세로, 가로, 색상 이렇게 되는것을 알 수 있습니다.

 

 


-Size

#(364, 548, 3)
h, w = img_color.shape[:2]
print(f'이미지 사이즈: {w} * {h}')

>>이미지 사이즈: 548 * 364

 

여기서 보면 h,w를 슬라이싱(:2니까 2기되기 전까지)해서 각각 h, w에 넣었다. 그래서 뽑아보니 잘 나오는것을 확인했다.


-그레이 스케일 영상인지, 컬러영상인지 구분하기

 

이 둘을 구분하는 방법은 shape니까 shape가 3이면 color라는거고 아니면 그레이스케일 이라는겁니다.

이거에 대한 구문을 만들어보자면 아래와 같습니다.

#그레이 스케일 영상인지, 컬러영상인지 구분하기
if len(img_gray.shape) ==3:
    print('컬러영상')
elif len(img_gray.shape) ==2:
    print('그레이스케일 영상')

 

좀 더 자세히 뜯어보자면 img_gray.shpae는 (x,x,x)혹은 (x,x)로 아웃풋이 나오게 되니까 그 길이를 이용해서 하게되는것입니다. 여기서 살짝 헷갈렸는데 중간print해보니까 알겠더라구요.

 


- img_color에 특정 색 정보로 영상을 출력해보기

예를들어서 내가 한 색상을 위에 덮고싶을때 한번 사용해볼 수 있다.

지금같은경우는 가로가 548, 세로가 368이니까 이중포문을 작성해서 이미지를 특정 색으로 덮어보려고 합니다.

>>핑크는 255,102,255입니다

 

for x in range(h):
    for y in range(w):
        img_color[x, y] = (255, 102, 255)

cv2.imshow('img_color', img_color)
cv2.waitKey()

이렇게 for문을 2번 돌려도 되지만 좀 더 간단하게 사용할 수 있는 코드는

img_color[:,:] = (255, 102, 255)

로 해도 한번에 쫙 덮히는것을 볼 수 있습니다.


- numpy를 이용한 임의적으로 이미지 만들기

쉽게말하면 행렬로 이미지를 만들 수 있다는것인데, 이미지는 3채널이 있으면 컬러이미지까지 가능하다는 점을 이용해서 

임의로 만들어보았다.

img1= np.zeros((240,320,3), dtype=np.uint8)
cv2.imshow('img1', img1)
cv2.waitKey()

 

. 세로 : 240 ❘ 가로 : 320 ❘ 채널:3(컬러)


img2= np.zeros((240,320), dtype=np.uint8)
cv2.imshow('img2', img2)
cv2.waitKey()

위에랑 같지만 다른점은 채널수가 없기때문에 그레이스케일에 해당하는 검정색이다.

세로 : 240 ❘ 가로 : 320 ❘ 그레이스케일


좀더 비교를 하기 위해서 img3을 만들어보겠다!

img3은 130을 곱해보려고하는데, zeros로 곱하면 모두 0이 돼서 검정색이 될거기때문에

ones행렬을 만들어보았다. 그러면 모두 130으로 채워진 240,320의 행렬이 나타날태니 색이 좀 다를것이다.

 

img3= np.ones((240,320), dtype=np.uint8) * 130
cv2.imshow('img3', img3)
cv2.waitKey()


img4= np.full((240,320,3),(255,102,25), dtype=np.uint8)
cv2.imshow('img4', img4)
cv2.waitKey()

img4는 np.full로 채울건데 np.full은 특정 크기의 배열을 원하는 값으로 채워서 생성하는 numpy함수입니다.

np.full(shape, fill_value, dtype=None)


#shape → 생성할 배열의 크기 (예: (240, 320, 3))
#fill_value → 채울 값 (예: (255, 102, 25))
#dtype → 데이터 타입 (예: np.uint8)

 

위가 기본이라는점은 다시한번 리마인드하면 좋을것같다.

 

나는 240,320,3 인 컬러의 배열을 생성할거고 색상은 255,102,25인 컬러를 넣을것이다.

dtype은 np.unit8로 픽셀 값이 아까 말했던 정수로 저장되게 할것이다.