OpenCV 이미지 히스토그램 분석 (cv2.calcHist())
1. 히스토그램이란?
히스토그램(histogram)은 이미지 내 픽셀 값의 분포를 나타내는 그래프입니다. 일반적으로 x축은 픽셀의 밝기 값(0~255 범위)을, y축은 해당 밝기 값을 갖는 픽셀의 개수를 나타냅니다. 히스토그램을 분석하면 이미지의 명암 분포, 대비, 밝기 등을 파악할 수 있습니다.
OpenCV에서는 cv2.calcHist() 함수를 사용하여 이미지의 히스토그램을 계산할 수 있습니다.
2. cv2.calcHist() 함수 설명
cv2.calcHist() 함수의 기본적인 사용법은 다음과 같습니다.
cv2.calcHist(images, channels, mask, histSize, ranges)
각 매개변수의 의미는 다음과 같습니다.
- images: 분석할 이미지 (리스트 형태로 전달)
- channels: 계산할 채널 인덱스 (0: 그레이스케일, 1: Blue, 2: Green, 3: Red)
- mask: 특정 영역만 분석할 때 사용하는 마스크 이미지 (전체를 분석할 경우
None) - histSize: 히스토그램의 빈(bin) 개수 (보통 256 사용)
- ranges: 픽셀 값 범위 ([0, 256])
3. 그레이스케일 이미지의 히스토그램 계산
다음 예제는 그레이스케일 이미지의 히스토그램을 계산하고 시각화하는 코드입니다.
예제 코드: 그레이스케일 이미지 히스토그램 분석
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 이미지 불러오기
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 히스토그램 계산
hist = cv2.calcHist([image], [0], None, [256], [0, 256])
# 히스토그램 시각화
plt.figure(figsize=(10, 5))
plt.plot(hist, color='black')
plt.title('Grayscale Histogram')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.xlim([0, 256])
plt.show()
이 코드는 다음과 같은 단계를 수행합니다.
cv2.imread()를 사용하여 그레이스케일 이미지를 불러옵니다.cv2.calcHist()함수를 사용하여 히스토그램을 계산합니다.matplotlib.pyplot을 활용하여 히스토그램을 그래프로 출력합니다.
4. 컬러 이미지의 히스토그램 분석
컬러 이미지(RGB 또는 BGR)의 히스토그램은 각 채널별로 개별적으로 분석할 수 있습니다. OpenCV는 기본적으로 BGR 형식을 사용하므로, 각 채널을 분리하여 히스토그램을 계산합니다.
예제 코드: 컬러 이미지의 히스토그램 분석
# 컬러 이미지 불러오기
image = cv2.imread('image.jpg')
# 각 채널별 히스토그램 계산
colors = ('b', 'g', 'r')
plt.figure(figsize=(10, 5))
for i, color in enumerate(colors):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.title('Color Histogram')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.xlim([0, 256])
plt.show()
이 코드에서는 다음 작업을 수행합니다.
cv2.imread()를 사용하여 컬러 이미지를 불러옵니다.- BGR 채널별로
cv2.calcHist()를 호출하여 히스토그램을 계산합니다. matplotlib.pyplot을 활용하여 BGR 색상별 히스토그램을 그래프로 출력합니다.
5. 마스크를 이용한 특정 영역 히스토그램 분석
이미지의 특정 영역만 히스토그램 분석을 수행하려면 마스크를 사용할 수 있습니다. 마스크는 분석할 영역을 흰색(255), 나머지 영역을 검은색(0)으로 설정한 이진 이미지입니다.
예제 코드: 마스크를 활용한 히스토그램 분석
# 이미지 불러오기
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 마스크 생성 (중앙 영역 선택)
mask = np.zeros(image.shape, dtype=np.uint8)
mask[100:300, 100:300] = 255 # 100x100~300x300 영역 선택
# 원본 이미지 및 마스크 적용된 이미지 시각화
masked_image = cv2.bitwise_and(image, image, mask=mask)
# 히스토그램 계산
hist_full = cv2.calcHist([image], [0], None, [256], [0, 256])
hist_masked = cv2.calcHist([image], [0], mask, [256], [0, 256])
# 히스토그램 비교
plt.figure(figsize=(10, 5))
plt.plot(hist_full, label='Full Image', color='gray')
plt.plot(hist_masked, label='Masked Region', color='red')
plt.title('Histogram with Mask')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.legend()
plt.xlim([0, 256])
plt.show()
이 코드에서는 다음 단계를 수행합니다.
- 특정 영역을 선택하는 마스크를 생성합니다.
cv2.bitwise_and()를 사용하여 마스크를 적용한 이미지를 만듭니다.- 원본 이미지와 마스크 적용된 영역의 히스토그램을 각각 계산하여 비교합니다.
6. 히스토그램 평활화 (Histogram Equalization)
히스토그램 평활화는 이미지의 대비를 향상시키는 기법으로, cv2.equalizeHist()를 사용하여 수행할 수 있습니다.
예제 코드: 히스토그램 평활화
# 히스토그램 평활화 적용
image_eq = cv2.equalizeHist(image)
# 결과 비교
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(image_eq, cmap='gray')
plt.title('Equalized Image')
plt.axis('off')
plt.show()
히스토그램 평활화를 적용하면 명암 대비가 개선되어 이미지의 세부 정보가 더욱 뚜렷하게 보일 수 있습니다.
7. 마무리
이 포스팅에서는 OpenCV의 cv2.calcHist()를 활용한 이미지 히스토그램 분석 방법을 다루었습니다. 기본적인 히스토그램 계산부터, 컬러 이미지 분석, 특정 영역만 분석하는 마스크 적용, 히스토그램 평활화까지 다양한 활용법을 살펴보았습니다.
히스토그램은 이미지의 특징을 파악하는 데 중요한 도구이므로, OpenCV를 활용한 이미지 처리 프로젝트에서 적극적으로 활용할 수 있습니다.
'Python > OpenCV' 카테고리의 다른 글
| OpenCV 윤곽선 검출 (cv2.findContours()) (0) | 2025.11.09 |
|---|---|
| OpenCV로 색상 히스토그램 평탄화 (cv2.equalizeHist()) (0) | 2025.11.08 |
| OpenCV 이미지 위에 텍스트 추가하기 (cv2.putText()) (0) | 2025.11.06 |
| Python OpenCV - 이미지 위에 선, 원, 사각형 그리기 (0) | 2025.11.05 |
| OpenCV를 활용한 엣지 검출 (Canny, Sobel, Laplacian) (0) | 2025.11.04 |