본문 바로가기
OpenCV

OpenCV 2차원 히스토그램 만들기.

by 187cm 2022. 4. 18.
반응형

OpenCV-Python으로 배우는 영상처리 및 응용.

Chapter 6 화소처리 Q14

 



우선 OpenCV내장함수 cv2.cvtColor(image, cv2.COLOR_BGR2HSV)를 사용하지 않고 변환공식은 이전 링크 에 적어두었다.

 

내장함수 사용하지않고 BGR2HSV 구현하기




이번에는 앞에서 만든 소스코드를 바탕으로 위에 문제에 맞는 2차원 히스토그램을 만들어보겠다.

2차원 Histogram을 만들기 위해서는 cv.calcHist() 를 사용하면 됩니다. 

cv2.calcHist([img], [0,1], [img_size], [img_range, color_range])

 

Point : two_dim_histo[hsv_img[row, col, 0], hsv_img[row, col, 1]] += 1

import numpy as np, cv2

image = cv2.imread("images/flor_pantar.jfif", cv2.IMREAD_COLOR)
if image is None : raise Exception("영상파일 읽기 오류")
if image.ndim != 3 : raise Exception("영상파일 차원 오류")

#HSV 칼라 공간 변화. 이번에는 빠르게 내장함수 사용.
# 내장함수 안쓰는건 이전 포스팅에 
hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# two dim histogram 구현, uint8로 8비트 단일 채널로 imshow에 출력할거야.
two_dim_histo = np.zeros((image.shape[:2]), np.uint8)

# calcHist
for row in range(hsv_img.shape[0]):
    for col in range(hsv_img.shape[1]):
        two_dim_histo[hsv_img[row, col, 0], hsv_img[row, col, 1]] += 1

 

  • 2중 for문으로 구현한 calcHist
    • 세로(row)가 Hue가 된다고 하였으니 hsv_img[row, col, 0] 이 들어간다.
    • 가로(col)이 Saturation이 된다고 하였으니 hsv_img[row, col, 1] 이 들어간다.
    • 각각 HSV에서 0, 1 채널이 H, S를 담당하고 있으니까.

히스토그램 스트레칭.

max_val = 23 # np.max(two_dim_histo)
two_dim_histo = (two_dim_histo/max_val) * 255
# round 불가능 -> np.array로 재정렬.
two_dim_histo = np.array(two_dim_histo, np.uint8)

1.max_val = 56 min_val = 0 이 나온다.

  • 이상하게 56은 뭔가 이상치 처럼 혼자 띄용하고 띄워져있다.
  • 따라서 위에서는 56이 아닌 23으로 넣어서 진행하였다. (56 다음 max_val이 23이다.)
  • 우리는 늘 해왔던 것 처럼 히스토그램 스트레칭을 진행하자.

2.근데 원래 max값은 23이 되어야 하는데...

  • 그림은 OpenCV-Python 으로 배우는 영상처리 및 응용 의 Chapter 6의 문제 14번의 사진을 그대로 가져왔다.

3.여기 까지의 출력 결과

  • 오른쪽 끝에 하얗게 보이는 부분이 이상치인 부분같다. max_val = 56이 나오게 된 이유

여기까지 했으면 80% 완료(근데 이해하기 가장 힘듬) 이제 color 색 입히기

  • 여기를 이해 못하는 사람이 많을거 같다. 나도 여기서 막혔다.
color_histo = np.zeros(image.shape, np.uint8) #3차원의 칼라를 넣을 image와 같은 3차원의 shape 생성.

for row in range(color_histo.shape[0]):
    for col in range(color_histo.shape[1]):
        color_histo[row, col] = [row, col, two_dim_histo[row, col]]
  • 사실 위의 two_dim_histo[hsv_img[row, col, 0], hsv_img[row, col, 1]] += 1 를 이해 했다면 이해가 수월할지도..?
    • two_dim_histo[row, col]은 Intensity 빈도수가 되어야 하니까
    • row, col이 왜 들어가야 하냐 위에서 row col이 Hue, Saturation에 따른 Intensity를 넣었기 때문이다.
    • 그러면 Hue와 Saturation의 상관관계를 보여야 하니까 row와 col이 들어가야징

마지막 문제 근데 출력하면 이상하게 나온다...

for row in range(color_histo.shape[0]):
    for col in range(color_histo.shape[1]):

        if two_dim_histo[row, col]>50:
            color_histo1[row, col] = [row, col, two_dim_histo[row, col]]

        color_histo2[row, col] = [row, col, two_dim_histo[row, col]]

cv2.imshow("colorHist1", color_histo1)
cv2.imshow("colorHist2", color_histo2)
  • 여기 까지의 출력 결과 :
    • 뭔가 된거 같지만 배경이 문제가 생긴다..
    • 마지막 intensity값이 50 이상 일때만 출력해 보아도 이상하다..

위의 그림은 BGR 채널이 아닌 HSV채널인걸 잊지말자.

  color_histo = cv2.cvtColor(color_histo, cv2.COLOR_HSV2BGR)
  cv2.imshow("color hist BGR", color_histo)

  cv2.imshow("hsv_plot", two_dim_histo)
  cv2.imshow("hsv_img", hsv_img)
  cv2.waitKey(0)

반응형

'OpenCV' 카테고리의 다른 글

BGR2HSV OpenCV 내장함수 없이 구현하기  (0) 2022.04.17