오늘의 목표는 두 개의 이미지의 유사도를 반환해 낼 거다.
1. 히스토그램 비교
가장 일반적인 방법인 히스토그램은 이미지의 각 픽셀 값의 빈도를 나타내는 그래프로, 픽셀 값들의 분포를 알 수 있다.
import cv2
import numpy as np
# 이미지 불러오기
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
# 히스토그램 계산
hist1 = cv2.calcHist([img1], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
hist2 = cv2.calcHist([img2], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
# 히스토그램 비교
similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
print(f"Histogram Similarity: {similarity}")
히스토그램 기반 유사도를 사용했을 때의 장단점은
장점
단순하고 빠르게 계산이 가능하다.
이미지의 전반적인 분포를 고려하기 때문에 일부 변형에 강한 성능을 봉리 수 있다.
(이미지의 크기와 해상도에 크게 영향을 받지 않는다.)
단점
히스토그램만으로는 이미지의 구조적 특성을 고려하지 않는다.
일부 색상 변화가 크지 않은 이미지에서는 제한된 성능을 보일 수 있다.
(질감이나 모양과 같은 다른 요소를 고려하지 못하고 색상에 대한 정보만을 고려한다.
2. 구조적 유사도(SSIM)
SSIM은 이미지의 구조적 유사성을 측정하는 방법이다.
pip install scikit-image
from skimage.metrics import structural_similarity as ssim
# 이미지 불러오기
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
# SSIM 계산
similarity_index, _ = ssim(img1, img2, full=True)
print(f"SSIM: {similarity_index}")
구조적 유사도의 장단점으로는
장점
이미지의 밝기, 대비 및 주조적 유사성을 고려하여 높은 정확도를 제공한다.
인간 시각 체계에 기반하고 있어 인간의 시각적 인식과 관련이 높다.
단점
계산 비용이 높아 대규모 이미지 데이터셋에 적용하기 어려울 수 있다.
이미지의 크기가 서로 다를 때 일부 적용 어려움이 있을 수 있다.
3. ORB 특징 매칭
ORB는 특징점을 찾아서 이미지 간의 매칭을 수행합니다. 'cv2.ORB_create()' 함수를 사용하여 ORB 디텍터와 매처를 생성하고 'detectAndCompute()' 메서드를 사용하여 특징점을 찾고 매칭할 수 있다.
import cv2
# 이미지 불러오기
img1 = cv2.imread('image1.jpg', 0)
img2 = cv2.imread('image2.jpg', 0)
# ORB 디텍터 및 매처 생성
orb = cv2.ORB_create()
# 특징점 및 디스크립터 계산
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# BFMatcher 생성 및 매칭
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
# 매칭 결과를 정렬하여 가장 좋은 매칭 추출
matches = sorted(matches, key=lambda x: x.distance)
# 매칭 결과 그리기
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow("Matches", img_matches)
cv2.waitKey(0)
cv2.destroyAllWindows()
ORB 특징 매칭의 장단점으로는
장점
회전, 크기 변화에 강한 특징을 찾을 수 있다.
매칭 결과를 시각적으로 확인할 수 있어 디버깅 및 분석이 용이하다.
단점
이미지의 일부 영역이나 텍스처가 부족한 경우에는 제대로 작동하지 않을 수 있다.
특징점 기반의 방법이므로 변형이 심한 이미지에는 적합하지 않을 수 있다.
상황에 따라 여러 방법을 결합하여 높은 정확도의 유사도 분석을 수행하기도 한다.
히스토그램과 구조적 유사도를 함께 사용하여 최종 유사도를 계산해 보자
import cv2
from skimage.metrics import structural_similarity as ssim
def calculate_histogram_similarity(img1, img2):
# 히스토그램 계산
hist1 = cv2.calcHist([img1], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
hist2 = cv2.calcHist([img2], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
# 히스토그램 비교
hist_similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
return hist_similarity
def calculate_ssim(img1, img2):
# SSIM 계산
similarity_index, _ = ssim(img1, img2, full=True)
return similarity_index
def combined_similarity(img1, img2, weight_hist=0.5, weight_ssim=0.5):
# 히스토그램 유사도 계산
hist_similarity = calculate_histogram_similarity(img1, img2)
# SSIM 유사도 계산
ssim_similarity = calculate_ssim(img1, img2)
# 가중 평균하여 종합적인 유사도 계산
combined_similarity = (weight_hist * hist_similarity) + (weight_ssim * ssim_similarity)
return combined_similarity
# 이미지 불러오기
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
# 종합적인 유사도 계산
similarity = combined_similarity(img1, img2)
print(f"Combined Similarity: {similarity}")
각 결과 값을 계산한 후 가중 평균하여 종합적인 유사도를 계산할 수 있다.
이때 weight_hist와 weight_ssim 매개변수는 각각의 유사도에 대한 가중치를 조절하는 데 사용된다.
'프로그래밍 > Python' 카테고리의 다른 글
[OpenCV] 이미지 분석 시작하기 - 창 관리, 그레이스케일 (1) | 2024.02.29 |
---|---|
[Pandas] Dataframe row apply 활용법 (0) | 2024.01.15 |
[Pandas] Dataframe row 순회하는 법 (0) | 2023.09.13 |
[Pandas] FutureWarning: iteritems is deprecated and will be removed in a future version. Use .items instead. for column, series in pdf.iteritems() 오류 해결 - Pandas 버전 맞추기 (0) | 2023.02.24 |
[Python] 도로명 주소 위도,경도로 전환하기 (지오코딩) (0) | 2022.11.02 |