[영상처리] Ch.06 화소처리

유빈·2024년 10월 29일

OpenCV

목록 보기
4/5
post-thumbnail

6.4 컬러 공간 변환

6.4.1 컬러 및 컬러 공간

    • 색각으로 느낀 빛에서 주파수(파장)의 차이에 따라 다르게 느껴지는 색상
      • 색각: 눈의 감각인 시각 가운데 하나의 감각
    • 보통 물체에 닿는 빛은 일부 흡수되고 일부 반사됨
    • 반사된 빛을 사람의 눈이 인지하는 것 = 물체의 색

  • 가시 광선
    • 전체 전자기파 중에서 인간이 인지할 수 있는 약 380nm ~ 780nm 사이의 파장

  • 컬러 공간
    • 색 표시계의 모든 색들을 색 공간에서 3차원 좌표로 표현한 것 (RGB, CMY, HSV 등)
    • 공간상의 좌표로 표현 -> 어떤 컬러와 다른 컬러들과의 관계를 표현하는 논리적인 방법 제공

  • 영상처리에서 컬러 공간 다양하게 활용
    • 각각의 색상이 다른 객체를 분리하기 위해
    • 전선의 연결 오류 검사를 위해
    • 기준 색상과 비슷한 색상의 전선인지를 체크하기 위해
    • 색상 정보를 이용하여 원하는 물체를 검색하기 위해


6.4.2 RGB 컬러 공간

  • RGB 컬러 공간
    • 가산 혼합 - 빛을 섞을수록 밝아짐
    • 빛을 이용해서 색 생성
    • 빛의 삼원색 (빨강, 초록, 파랑)
      • 원색: 더 이상 분해할 수 없는 최소한의 색
      • black (0, 0, 0), white (255, 255, 255),
        red (255, 0, 0), green (0, 255, 0), blue (0, 0, 255)
    • 모니커, TV, 빔 프로젝터 등의 디스플레이 장비들에서 기본 컬러 공간으로 사용됨


6.4.3 CMY(K) 컬러 공간

  • CMY 컬러 공간
    • 감산 혼합 - 섞을수록 어두워지는 방식
    • 색의 삼원색 (청록, 자홍, 노랑)
      • 빛의 삼원색과 보색 관계
      • 원색들은 흰색으로부터 감산되어 색이 만들어짐

  • CMYK 컬러 공간
    • 순수한 검정색 사용
    • CMY 컬러 모델에 검은색 추가
    • 장점: 뛰어난 대비 제공 (검정 잉크가 컬러 잉크보다 비용 낮음)
    • CMY -> CMYK 컬러 공간으로 변환하는 수식
      blacK = min(Cyan, Magenta, Yellow)
      Cyan = Cyan - blacK
      Magenta = Magenta - blacK
      Yellow = Yellow - blacK


예제 6.4.1) 컬러 공간 변환 (BGR -> CMY)

import numpy as np, cv2

BGR_img = cv2.imread("images/color_model.jpg", cv2.IMREAD_COLOR)
if BGR_img is None: raise Exception("영상 파일 읽기 오류")

white = np.array([255, 255, 255], np.uint8)
# RGB와 CMY는 보색 관계니까 white에서 빼서 보색으로 만들어 줌
CMY_img = white - BGR_img  
Yellow, Magenta, Cyan = cv2.split(CMY_img)  # 채널 분리

titles = ['BGR_img', 'CMY_img', 'Yellow', 'Magenta', 'Cyan']
for t in titles:    cv2.imshow(t, eval(t))
cv2.waitKey(0)


컬러 영상의 각 채널을 반전해서 CMY_img 행렬을 만든다.

C = 255 - R
M = 255 - G
Y = 255 - B

R = 255 - C
G = 255 - M
B = 255 - Y



예제 6.4.2) 컬러 공간 변환 (BGR -> CMYK)

import numpy as np, cv2

BGR_img = cv2.imread("images/color_model.jpg", cv2.IMREAD_COLOR)
if BGR_img is None: raise Exception("영상 파일 읽기 오류")

white = np.array([255, 255, 255], np.uint8)
CMY_img = white - BGR_img
CMY = cv2.split(CMY_img)

# 원소 간의 최솟값 저장
# 최솟값을 black으로 지정해서 빼줘야 음수값이 나오지 않음
black = cv2.min(CMY[0], cv2.min(CMY[1], CMY[2]))
Yellow, Magenta, Cyan = CMY - black  # 3개 행렬 화소값 차분 

titles = ['black', ' Yellow', 'Magenta', 'Cyan']
[cv2.imshow(t, eval(t)) for  t in titles]
cv2.waitKey(0)



6.4.4 HSI 컬러 공간

  • 인간이 컬러 영상 정보를 인지하는 방법
    • 색상(Hue), 채도(Saturation), 명도(Intensity, Value)로 분류

  • HSI 컬러 공간
    • 인간이 색상을 인식하는 3가지 요인인 색상, 채도, 명도를 컬러 공간으로 옮긴 것
    • 색상 H - 각도
      • 빛이 물체에 반사되어 나온 색
      • 파장을 시각적으로 표현한 것
      • 원판의 0~360도까지 회전
    • 채도 S - 반지름
      • 색의 순수한 정도
      • 흰색의 혼합 비율에 따라서 0(순도 낮음) ~ 100(순도 높음)
        • 빨간색 = 100, 핑크색 = 흰색 비율에 따라 0에 가까워짐
    • 명도 I - 원뿔의 높이
      • 빛의 세기
      • 색의 밝고 어두운 정도
      • 가장 아래쪽 0 = 검은색, 가장 위쪽 100 = 흰색

import numpy as np, cv2, math

def calc_hsi(bgr):
    # B, G, R = bgr.astype(float)                           # float 형 변환
    B, G, R = float(bgr[0]), float(bgr[1]), float(bgr[2])       # 속도면에 유리
    bgr_sum = (R + G + B)
    # 색상 계산
    tmp1 = ((R - G) + (R - B)) * 0.5
    tmp2 = math.sqrt((R - G) * (R - G) + (R - B) * (G - B))
    angle = math.acos(tmp1 / tmp2) * (180 / np.pi) if tmp2 else 0

    H = angle if B <= G else 360 - angle
    S = 1.0 - 3 * min([R, G, B]) / bgr_sum if bgr_sum else 0
    I = bgr_sum / 3                                                # 명도 계산
    return (H/2, S*255, I)

# BGR 컬러 -> HSI 컬러
def bgr2hsi(image):
    hsv = [[calc_hsi(pixel) for pixel in row] for row in image ]   # 2차원 배열 순회
    return (np.array(hsv)).astype('uint8')

BGR_img = cv2.imread("images/color_space.jpg", cv2.IMREAD_COLOR) # 컬러 영상 읽기
if BGR_img is None: raise Exception("영상 파일 읽기 오류")

HSI_img = bgr2hsi(BGR_img)                  # BGR를 HSI로 변환
HSV_img = cv2.cvtColor(BGR_img, cv2.COLOR_BGR2HSV) # OpenCV 함수
Hue, Saturation, Intensity = cv2.split(HSI_img)                    # 채널 분리
Hue2, Saturation2, Intensity2 = cv2.split(HSV_img) 					# 채널 분리

titles = ['BGR_img','Hue','Saturation','Intensity']
[cv2.imshow(t, eval(t)) for t in titles]
[cv2.imshow('OpenCV_'+t, eval(t+'2')) for t in titles[1:]]	# OpenCV 결과 영상 표시
cv2.waitKey(0)



RGB에서 HIS 컬러 공간으로 변환이 필요한 시점

  1. 색상 조정
  2. 명도 조절
  3. 이미지 필터링
profile
🌱

0개의 댓글