[CV] #10. 컬러 영상 처리

Jnary·2024년 1월 20일
0

Computer Vision

목록 보기
12/18
post-thumbnail

#10-1. 컬러 영상 다루기

컬러 영상 픽셀값 참조

  • BGR 색상 순으로 픽셀 값 표현
  • 색상 성분 값 : 0~255 (uchar 자료형)
  • Vec3b 자료형 : 컬러영상의 한 픽셀 정확하게 표현 → python : uint8
src = cv2.imread('cat.bmp', cv2.IMREAD_COLOR)
print('src.shape: ', src.shape)
# src.shape: (1666, 1666, 3)
print('src.dtype: ', src.dtype)
# src.dtype: uint8
print('The pixel value [B, G, R] at (0, 0): ', src[0,0])
# The pixel value [B, G, R] at (0, 0): [205 196 123]

컬러 영상 반전 inverse

  • B,G,R 각각에서 255 빼는 연산
dst = np.zeros(src.shape, src.dtype)
for j in range(src.shape[0]):
    for i in range(src.shape[1]):
        p1 = src[j, i]
        p2 = dst[j, i]
        p2[0] = 255 - p1[0]
        p2[1] = 255 - p1[1]
        p2[2] = 255 - p1[2]

색 공간 변환

  • cvtColor(src, dst, code, dstCn = 0)

  • COLOR_BGR2RGB, COLOR_RGB2BGR

  • COLOR_BRG2GRAY

    • 3채널 BGR → 1채널 GRAY
    • 연산 속도, 메모리 사용량 감소
    • Y = 0.299R + 0.587G + 0.114B
  • COLOR_GRAY2BGR

    • R = G = B = Y
    • 그레이스케일 영상 위에 색깔 있는 선, 글씨 나타내기 위해 사용
  • BGR2HSV, HSV2BGR

    • HSV : 색상(hue), 채도(saturation), 명도(value)
    • 명도 : 빛의 세기
    • 색상 : 원뿔을 가로로 잘랐을 때 나타나는 원형의 각도 → 0도일 때 빨간색
    • 채도 : 원 모양 중심에서 최솟값
    • BGR2HSV : H(0~179), S,V(0~255) → 256이상의 정수(360도) 표현 X, 각도/2값 저장
  • BGR2YCrCb, YCrCb2BGR

    • Y성분 = 밝기 (휘도 luminance) → 그레이스케일 계산 공식과 동일
    • Cr, Cb성분 = 색상 (색차 chrominance)
    • 그레이스케일 정보, 색상정보 분리하여 처리할 때 유용
    • 각 성분값 0~255

색상 채널 나누기

src = cv2.imread('jnary.png', cv2.IMREAD_COLOR)
bgr_planes = cv2.split(src)
cv2.imshow('B_plane', bgr_planes[0])
#파란색 성분은 흰색으로, 나머지는 검정색
cv2.imshow('G_plane', bgr_planes[1])
cv2.imshow('R_plane', bgr_planes[2])
# 합치기
dst = cv2.merge(bgr_planes)

#10-2. 컬러 영상 처리 기법

컬러 히스토그램 평활화

  • equalizeHist() : 그레이스케일 영상만 입력 받음
  • 입력 영상 R, G, B 채널로 나눈 후 채널별로 히스토그램 평활화 수행 후 다시 합치기
  • 단점 : R, G, B 색상 채널마다 서로 다른 형태의 명암비 변환 함수 사용 → 원본 영상과 다른 색상의 결과 영상 만들어짐
  • 색감 변경X, 명암비 높이려면 밝기 정보만 이용
    • YCrCb 색공간에서 Y 성분에 대해서만 히스토그램 평활화 수행
src_ycrcb = cv2.cvtColor(src, cv2.COLOR_BGR2YCrCb)
ycrcb_planes = cv2.split(src_ycrcb)
ycrcb_planes[0] = cv2.equalizeHist(ycrcb_planes[0])
dst_ycrcb = cv2.merge(ycrcb_planes)
dst = cv2.cvtColor(dst_ycrcb, cv2.COLOR_YCrCb2BGR)

색상 범위 지정에 의한 영역 분할

  • 특정 색상 영역 추출하는 작업 ex. 빨간색 픽셀 → 빨간색 객체의 위치, 크기 알아내기
  • 색상영역 구분 시, HSV의 색상(H) 정보가 설정된 색 공간 사용하는 것이 유리
  • inRange(src, lowerb, upperb) : 특정 범위 내에 존재하는지
    • 포함되어있으면 흰색, 그렇지 않으면 검정색
    • 그레이스케일 영상, 다채널 영상 모두 지정 가능
    • 입력 영상의 각 채널 값이 모두 지정된 범위를 만족할 때 255 → lowerb, upperb에 Mat 객체 지정 가능 (각기 다른 하한값, 상한값)
def on_hue_change(_=None):
    lower_hue = cv2.getTrackbarPos('Lower Hue', 'mask')
    upper_hue = cv2.getTrackbarPos('Upper Hue', 'mask')
    lowerb = (lower_hue, 100, 0)
    upperb = (upper_hue, 255, 255)
    mask = cv2.inRange(src_hsv, lowerb, upperb)
    cv2.imshow('mask', mask)
def main():
    global src_hsv
    src_hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
    cv2.imshow('src', src)
    cv2.namedWindow('mask')
    cv2.createTrackbar('Lower Hue', 'mask', 40, 179, on_hue_change)
    cv2.createTrackbar('Upper Hue', 'mask', 80, 179, on_hue_change)
    on_hue_changed(0)
    cv2.waitKey()
    cv2.destroyAllWindows()

히스토그램 역투영

  • HSV : 원색에 가까운 색상 찾기는 효과적 → 피부색처럼 미세한 변화, 색상값을 수치적으로 지정하기 어려운 경우 적합 X
  • 기준 영상으로부터 찾고자 하는 객체의 컬러 히스토그램 → 해당 히스토그램에 부합하는 영역 찾아내는 방식
  • histogram backprojection
    • 주어진 히스토그램 모델과 일치하는 픽셀을 찾아내는 기법
  • calcBackProject(images, nimages, channels, hist, backProject, ranges, scale = 1, uniform = true)
ref = cv2.imread('ref.png', cv2.IMREAD_COLOR)
mask = cv2.imread('mask.bmp', cv2.IMREAD_GRAYSCALE)
ref_ycrcb = cv2.cvtColor(ref, cv2.COLOR_BGR2YCrCb)
channels = [1, 2]
cr_bins = 128
cb_bins = 128
histSize = [cr_bins, cb_bins]
cr_range = [0, 256]
cb_range = [0, 256]
ranges = cr_range + cb_range

hist = cv2.calcHist([ref_ycrcb], channels, mask, histSize, ranges)
src = cv2.imread('kids.png', cv2.IMREAD_COLOR)
src_ycrcb = cv2.cvtColor(src, cv2.COLOR_BGR2YCrCb)
backproj = cv2.calcBackProject([src_ycrcb], channels, hist, ranges, 1)
cv2.imshow('src', src)
cv2.imshow('backproj', backproj)
cv2.waitKey()
cv2.destroyAllWindows()

RANSAC

  • Random Sample Consensus
  • 직선 검출에 이용 가능
  • random한 두 점으로 직선 만들고 위아래 버퍼 주기 → 그 안 공간에 edge들 많이 있으면 직선이라고 판단
  • noise 영향에 강건함, 빠른 처리
  • 최대 단점 : 지정된 횟수만큼 random한 두 점 선정 → 약간 다르거나 못 찾을 수도 있음
profile
숭실대학교 컴퓨터학부 21

0개의 댓글