[OpenCV] 04-1. Changing Colorspaces
🐍Python/OpenCV

[OpenCV] 04-1. Changing Colorspaces

728x90
반응형

< 4-1. Changing Colorspaces >

  • 이 튜토리얼에서는 하나의 컬러 공간의 이미지를 다른 공간으로 변환하는지를 배울 것이다. (ex. BGR -> Gray / BGR -> HSV 등)
  • 추가적으로, 비디오에서 색이 있는 객체를 추출하는 기능을 만들어 볼 것이다.
  • cv2.cvtColor(), cv2.inRange()에 대해서 배울 것이다.

Changing Color-space

OpenCV에는 150개 이상의 색상 공간 변환 방법이 있다. 하지만 하지만 가장 자주 널리 사용되는 BGR -> Gray 와 BGR -> HSV를 볼 것이다.

색상 변환에서, cv2.cvtColor(input_img,flag) 함수를 사용하는데 flag는 변환의 종류를 결정한다.

BGR -> Gray 변환에 대해서는 cv2.COLOR_BGR2GRAY를 사용한다. 유사하게 BGR -> HSV에서는, cv2.COLOR_BGR2HSV flag를 사용한다. 다른 종류의 flag를 보고 싶다면 아래의 코드를 실행하면 된다.

import cv2
import numpy as np
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)

총 274개의 flags가 존재하는 것을 확인할 수 있다.

HSV에서 색조(H)의 범위는 [0,179], 채도(S) 범위는 [0,255], 명도(V)의 범위는 [0,255]이다. 다른 소프트웨어에서는 다른 스케일을 사용한다. 그러니 OpenCV에서 그드를 비교하려면, 범위를 정규화하여야 한다.

Object Tracking

이제 BGR 이미지를 HSV로 변환하는 법을 알았으니, 채색된 객체를 추출하는데 사용할 수 있다. HSV는 RGB 색공간에서 보다 색을 표현하기가 쉽다. 우리의 기능에서는, 파랗게 채색된 객체를 추출하려 한다. 아래에 방법이 있다.

  • 비디오에서 각각의 프레임을 받는다
  • BGR에서 HSV 색 공간으로 변환한다
  • 파란색 범위의 HSV 이미지를 기준점으로 설정한다.
  • 파란색 객체만을 추출하고, 우리는 우리가 원하는 그 이미지로 무엇이든 할 수 있다.

아래 코드를 보자.

cap = cv2.VideoCapture(0)

while(1):

    # 각 프레임을 받아들인다. 
    _ , frame = cap.read()

    # BGR을 HSV로 변환한다.
    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)

    # HSV에서 파란색 범위를 정의한다.
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])

    # 파란색만 가져오도록 HSV이미지의 기준점을 정한다.
    mask = cv2.inRange(hsv,lower_blue,upper_blue)

    # bitwise_and 마스크 및 원본 이미지
    res = cv2.bitwise_and(frame,frame,mask=mask)

    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()

원본 이미지

Mask 이미지

최종 결과 이미지


파란색 물건을 들고 카메라에 서니 파란색 계열만 인식하는 것을 볼 수 있다.

How to find HSV values to track?

이는 Stackoverflow에서 흔히 볼 수 있는 질문이다. cv2.cvtColor()을 사용하여 간단하게 알 수 있다. 이미지를 보내는 대신, 원하는 BGR 값을 보내면 된다. 예를 들어, HSV에서 초록색 값을 알고 싶다면 아래처럼 해보면 된다.

green = np.uint8([[[0,100,100]]])
yellow = np.uint8([[[0,255,255]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
hsv_yellow = cv2.cvtColor(yellow,cv2.COLOR_BGR2HSV)
print(hsv_green)

import matplotlib.pyplot as plt

plt.subplot(2,2,1)
plt.title('Green')
plt.imshow(hsv_green[:,:,::-1])
plt.axis('off')
plt.subplot(2,2,2)
plt.title('Yellow')
plt.imshow(hsv_yellow[:,:,::-1])
plt.axis('off')


[H-10,100,100]을 최소값으로 [H+10,255,255]를 최대값으로 각각 준다. 이 방법외에도, 이러한 값을 찾기 위해 GIMP나 온라인 컨버터와 같은 이미지 편집 도구를 사용할 수 있지만 HSV 범위를 조정하는 것을 잊으면 안된다.


  • 각 BGR 색만을 추출하여 인식하는 것을 만들기
cap = cv2.VideoCapture(0)

while(1):
    # 각 프레임을 받아들인다. 
    _ , frame = cap.read()

    # BGR을 HSV로 변환한다.
    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)

    # HSV에서 BGR의 범위를 각각 정의한다.
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])

    lower_green = np.array([50,100,100])
    upper_green = np.array([70,255,255])

    lower_red = np.array([-10,100,100])
    upper_red = np.array([10,255,255])

    # BGR을 각각 가져오도록 HSV이미지의 기준점을 정한다.
    mask_b = cv2.inRange(hsv,lower_blue,upper_blue)
    mask_g = cv2.inRange(hsv,lower_green,upper_green)
    mask_r = cv2.inRange(hsv,lower_red,upper_red)

    # bitwise_and 마스크 및 원본 이미지
    res_b = cv2.bitwise_and(frame,frame,mask=mask_b)
    res_g = cv2.bitwise_and(frame,frame,mask=mask_g)
    res_r = cv2.bitwise_and(frame,frame,mask=mask_r)

    cv2.imshow('Original',frame)
    cv2.imshow('Blue',res_b)
    cv2.imshow('Green',res_g)
    cv2.imshow('Red',res_r)    
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()


파란색 사진

위와 동일하다


초록색 사진

방에 초록색이 네이버밖에 없어서 네이버로 인식을 해봤다.


빨간색 사진

핸즈온 머신러닝이 빨간색이라 인식시켜 봤다.

728x90
반응형