Computer VIsion/기초(OpenCV)

Opencv를 이용하여 이미지 히스토그램 구현하기

JackSmith 2024. 8. 23.

 

오늘은 Opencv를 이용하여 이미지를 가져와 어떤 밝기의 픽셀이 가장 빈도수가 높은지를 히스토그램으르 나타내보겠습니다.

 

1. 히스토그램 정의

히스토그램이란?

히스토그램이란, 이미지 밝기 분포를 그래프로 나타낸 것으로, 가로축은 0에서 256까지 픽셀의 밝기값으로 구성되고, 세로축은 밝기 값을 갖는 픽셀의 빈도수를 의미합니다.

 

 

2. 이미지 히스토그램 구현하기

import numpy as np
import cv2
import matplotlib.pyplot as plt
img1 = cv2.imread('./assets/images/siba.jpg',0)
img2 = cv2.imread('./assets/images/wow_siba.jpg',0)
hist1 = cv2.calcHist([img1], [0], None, [256], [0, 256])
hist2 = cv2.calcHist([img2], [0], None, [256], [0, 256])
  • cv2.calcHist() 함수는 이미지의 히스토그램을 계산하는 함수입니다.
    • `images`: 히스토그램을 계산할 이미지의 array, 대괄호로 묶어서 리스트 형태로 전달된다.
    • `channels`: 채널의 인덱스를 나타내는 array, 컬러 이미지일 경우 B[0], G[1], R[2] 3개의 채널을 쓸 수 있다.
    • `mask`: 이미지의 특정부분만 계산하고 싶을때 사용하는 마스크
    • `histSize`: 각 차원의 히스토그램 크기를 나타내는 배열
    • `ranges`: 각 차원의 히스토그램 범위
plt.figure(figsize=(12,8))
plt.subplot(221)
plt.imshow(img1, 'grey')
plt.title('siba')

plt.subplot(222)
plt.imshow(img2, 'grey')
plt.title('wow_siba')

plt.subplot(223)
plt.plot(hist1, color='y')
plt.title('siba_HISTOGRAM')
plt.xlim([0, 256])

plt.subplot(224)
plt.plot(hist2, color='y')
plt.title('wow_siba_HISTOGRAM')
plt.xlim([0, 256])

plt.show()

 

결과:

 

고찰:

히스토그램으로 이 사진이 어떤 밝기를 가지는지를 대략적으로 살펴볼 수 있었다.

 

3. Mask를 적용해서 히스토그램 구현하기

코드:

# 1.이미지 로딩
img3 = cv2.imread('./assets/images/flower_siba.jpg',0)

# # 2.이미지와 그 형태(shape) 출력
print(img3,'\n')
print(img3.shape) #2차원이미지 (height(y), width(x))

결과:

# 3.이미지 컬러 변환
img3 = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB)

# 4.마스크 생성 및 적용
mask = np.zeros(img3.shape[:2], np.uint8)
mask[20:120, 100:200] = 255
masked_img = cv2.bitwise_and(img3, img3, mask=mask)

# 5.히스토그램 계산
hist_full = cv2.calcHist([img3], [1], None, [256], [0, 256])
hist_mask = cv2.calcHist([img3], [1], mask, [256], [0, 256])

# 6.이미지 표시
plt.rcParams['font.family'] ='Malgun Gothic'
plt.rcParams['axes.unicode_minus'] =False

plt.figure(figsize=(14,14))
plt.subplot(221)
plt.imshow(img3, 'gray')
plt.title('Original Image')

plt.subplot(222)
plt.imshow(mask, 'gray')
plt.title('Mask')

plt.subplot(223)
plt.imshow(masked_img, 'gray')
plt.title('Masked Image')

plt.subplot(224)
plt.title('Histogram')
plt.xlabel('밝기값')
plt.ylabel('빈도수', rotation=0)
plt.gca().yaxis.set_label_coords(-0.1, 0.1)
plt.plot(hist_full, color='r')
plt.plot(hist_mask, color='b')
plt.xlim([0, 256])

plt.show()

처음에 특정경로에서 이미지파일을 불러올때 그 이미지는 위와 같이 rgb 컬러의 채널이 B-G-R의 순서로 되어 있는 경우가 많습니다. 그래서 이를 해결하기 위해 cv2.cvtColor()함수를 사용하게 됩니다.

 

댓글