안녕하세요! 오늘은 그동안 배운 OpenCV의 다양한 기능을 활용하여 이미지 유사도 비교, 얼굴 합성, 그리고 모션 감지 CCTV를 직접 구현해보는 실습 위주의 내용을 정리해 보겠습니다. 히스토그램 연산과 프레임 차이 분석을 실무에 어떻게 적용하는지 확인해 보시기 바랍니다.
1. 이미지 유사도 비교 (Image Similarity)
이미지의 히스토그램 분포가 비슷하면 유사한 이미지일 확률이 높다는 점을 이용합니다. OpenCV는 두 히스토그램을 비교하는 cv2.compareHist() 함수를 제공합니다.
- 주요 알고리즘:
- cv2.HISTCMP_CORREL: 상관관계 (1에 가까울수록 일치)
- cv2.HISTCMP_CHISQR: 카이제곱 (0에 가까울수록 일치)
- cv2.HISTCMP_INTERSECT: 교차 (1에 가까울수록 일치)
📍 핵심 코드
# 이미지 읽기 및 HSV 변환
hsv_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
hsv_img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
# 히스토그램 계산 및 정규화
hist1 = cv2.calcHist([hsv_img1], [0, 1], None, [180, 256], [0, 180, 0, 256])
cv2.normalize(hist1, hist1, 0, 1, cv2.NORM_MINMAX)
hist2 = cv2.calcHist([hsv_img2], [0, 1], None, [180, 256], [0, 180, 0, 256])
cv2.normalize(hist2, hist2, 0, 1, cv2.NORM_MINMAX)
# 상관관계 비교
ret = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
print(f"유사도: {ret}")
2. 사람 얼굴과 해골 합성 (Face Blending)
단순히 두 이미지를 절반으로 자르는 것이 아니라, 경계선 부분의 알파 값을 서서히 조절하여 자연스럽게 합성하는 기법입니다.
📍 핵심 로직
- 합성할 두 이미지의 중앙 영역을 알파 블렌딩 범위로 지정합니다.
- 반복문을 통해 왼쪽에서 오른쪽으로 갈수록 첫 번째 이미지의 비중(alpha)을 낮추고, 두 번째 이미지의 비중(beta)을 높이며 픽셀 값을 연산합니다.
# 알파 블렌딩 적용 구간 반복
for i in range(alpha_width + 1):
alpha = (100 - step * i) / 100 # 1에서 0으로 감소
beta = 1 - alpha # 0에서 1로 증가
# 특정 열(column)에 대해 가중치 합성 수행
img_comp[:, start + i] = img_face[:, start + i] * alpha + img_skull[:, start + i] * beta
3. 움직임 감지 CCTV (Motion Detection)
단순히 전후 프레임의 차이만 구하면 미세한 노이즈에도 반응합니다. 이를 방지하기 위해 연속된 3개의 프레임(a, b, c)을 비교하는 알고리즘을 사용합니다.
- 알고리즘 원리: (A와 B의 차이) AND (B와 C의 차이)가 모두 발견되는 경우에만 움직임으로 간주합니다.
📍 핵심 코드
# 프레임 간 차이 계산
diff1 = cv2.absdiff(a_gray, b_gray)
diff2 = cv2.absdiff(b_gray, c_gray)
# 이진화 및 AND 연산
_, diff1_t = cv2.threshold(diff1, thresh, 255, cv2.THRESH_BINARY)
_, diff2_t = cv2.threshold(diff2, thresh, 255, cv2.THRESH_BINARY)
diff = cv2.bitwise_and(diff1_t, diff2_t)
# 모폴로지 연산으로 잔상 노이즈 제거
k = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
diff = cv2.morphologyEx(diff, cv2.MORPH_OPEN, k)
# 차이가 발생한 영역에 사각형 표시
if cv2.countNonZero(diff) > max_diff:
nzero = np.nonzero(diff)
cv2.rectangle(draw, (min(nzero[1]), min(nzero[0])), (max(nzero[1]), max(nzero[0])), (0, 255, 0), 2)
🛠️ 실무 활용 팁
- 유사도 비교: 단순 BGR보다는 조명 변화에 강한 HSV 색상 공간에서 분석하는 것이 훨씬 정확합니다.
- 노이즈 제거: 모션 감지 시에는 cv2.morphologyEx의 열림(OPEN) 연산을 꼭 활용하여 자잘한 노이즈를 지워야 오작동을 줄일 수 있습니다.
- 성능 최적화: 고해상도 영상을 그대로 처리하면 속도가 느려지므로, 분석 시에는 해상도를 낮추거나 특정 ROI만 지정하여 연산량을 줄이십시오.
🚀 마치며
지금까지 배운 OpenCV의 기초 이론들이 실제 실습에서 어떻게 조합되는지 확인해 보았습니다. 특히 3프레임 차이 분석을 통한 모션 감지는 보안 시스템이나 자동화 모니터링의 기본이 되는 아주 중요한 기술입니다.
궁금하신 점은 댓글로 남겨주시기 바랍니다. :)
반응형
'컴퓨터 과학 > 👀 컴퓨터 비전' 카테고리의 다른 글
| 📸 [OpenCV 기초] 리매핑(Remapping)과 렌즈 왜곡(Distortion) 완벽 정리 (0) | 2026.01.07 |
|---|---|
| 📸 [OpenCV 기초] 이미지 이동, 확대/축소, 회전 완벽 정리 (0) | 2026.01.07 |
| 📸 [OpenCV 기초] 2차원 히스토그램과 역투영(Back Projection) 완벽 정리 (0) | 2026.01.07 |
| 📊 [OpenCV 기초] 히스토그램과 화질 개선 (정규화, 평탄화, CLAHE) (0) | 2026.01.07 |
| 🖼️ [OpenCV 기초] 이미지 연산과 합성 (블렌딩, 마스킹) (0) | 2026.01.07 |