[Pillow] 이미지 유사도 비교 (Cosine Similarity)

도룩·2023년 12월 20일
0

목적

코사인 유사도를 이용해 두 이미지가 얼마나 유사한지 알 수 있다. (참고한 블로그)

설명

이전 포스트 중에 두 벡터의 내적(Dot product)을 설명하는 포스트에서 잠깐 코사인 유사도를 언급한 적이 있다.
이를 이용해 두 이미지의 유사도를 대략적으로 측정해볼 수 있다.
코드를 각 단계별로 설명하자면 다음과 같다.

  1. 이미지 크기를 10 x 10 으로 resizing 한다.
    • 더 정밀하게 유사도 비교가 필요하다면 resizing을 사용하지 않거나, resizing 사이즈를 더 크게 조정한다.
  2. 255로 나누어 값을 0 ~ 1 사이로 정규화 한다.
  3. 10 x 10 x 3의 3 차원 이미지를 (300, )의 vector로 변환한다.
  4. 코사인 유사도를 구한다.

환경

python 3.8.16
Pillow 10.1.0
numpy 1.24.4

Code

import os
import numpy as np
from PIL import Image

def mini_img(img_path, resize_shape = (10, 10)):
	img = Image.open(img_path)
    img = img.resize(resize_shape)
    return img

def cosine_similarity(img1, img2):
    array1 = np.array(img1)
    array2 = np.array(img2)
    assert array1.shape == array2.shape
    
    h, w, c = array1.shape
    len_vec = h * w * c
    vector_1 = array1.reshape(len_vec,) / 255.
    vector_2 = array2.reshape(len_vec,) / 255.

    cosine_similarity = np.dot(vector_1, vector_2) / (np.linalg.norm(vector_1) * np.linalg.norm(vector_2))
    return cosine_similarity
img1_path = "./test_img1.jpg"
img2_path = "./test_img2.jpg"

img1 = mini_img(img1_path)
img2 = mini_img(img2_path)

score = cosine_similarity(img1, img2)

 

\\

특징

  1. Vector가 0~1사이의 양수공간에 한정되어 있기 때문에 유사도를 직관적으로 알 수 있다.
    코사인 유사도 특성 상 vector 가 음수, 양수 공간에도 존재할 수 있다면 두 벡터의 방향이 다를 때 코사인 유사도 값은 음수값이 나올 수도 있다. 하지만 이미지 데이터 특성상 vector는 양수 공간에만 존재하기 때문에 코사인 유사도 값은 0과 1 사이 값이 나오게 되므로 두 이미지의 유사도를 직관적으로 % 로 표현이 가능해진다.
  2. 유사도의 정밀도를 목적에 맞게 조정할 수 있다.
    정밀한 유사도 비교가 필요하다면 resize를 크게 하거나 resize를 사용하지 않고 비교할 수 있다. (유동적으로 조정가능)

0개의 댓글

관련 채용 정보