본문 바로가기

Theory/DataScience

mahotas를 이용한 유사 이미지 찾기

Mahotas를 소개해 드린 적이 있습니다. 월리를 찾아라~에서요^^ 그 mahotas를 사용해서 어떤 이미지와 유사한 이미지를 찾아볼 수 있습니다. 오늘 예지는 Building Machine Learning Systems with Python라는 책의 예제입니다. 이미지 데이터는 해당 책의 github 사이트에서 받을 수 있습니다.

이미지를 보면, 저렇게 건물 사진 30장,

자연 경관 사진 30장,

문서 사진 30장이 있습니다. 각각 용량이 1~1.5메가 정도라 생각보다는 전체 용량이 좀 됩니다.

import mahotas as mh
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline

image = mh.imread('SimpleImageDataset/scene00.jpg')

plt.figure(figsize=(8,8))
plt.imszxhow(image)
plt.show()

살짝 하나만 읽어볼까요...

깔끔합니다.

from glob import glob

images = glob('SimpleImageDataset/*.jpg')

features = []
labels = []
for im in images:
    labels.append(im[19:-len('00.jpg')])
    im = mh.imread(im)
    im = mh.colors.rgb2gray(im, dtype=np.uint8)
    features.append(mh.features.haralick(im).ravel())
    
features = np.array(features)
labels = np.array(labels)

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

clf = Pipeline([('preproc', StandardScaler()), ('classifier', LogisticRegression())])

from sklearn import cross_validation

cv = cross_validation.LeaveOneOut(len(images))

scores = cross_validation.cross_val_score(clf, features, labels, cv=cv)
print('Accuracy: {:.2%}'.format(scores.mean()))

일단,  파일명에서 라벨링할 라벨을 추출(정말 다행입니다. 노가다 안해도 되어서)하고, 이미지의 질감에 대해 2차원 특징을 추출하는 알고리즘 중 하나인 haralick이라는 방법을 사용합니다. 그래서 각 그림의 feature를 추출하고, 로지스틱 회귀 분류기를 사용합니다. LOOCV(leave-one-out-cross-validation)를 사용해서 학습과 평가를 수행하구요. 그 결과는 대략 81%쯤 나옵니다.

sc = StandardScaler()
features = sc.fit_transform(features)
from scipy.spatial import distance
dists = distance.squareform(distance.pdist(features))

이제 추출된 feature로 각각의 이미지간 거리를 구해 놓습니다.

그러면 첫 번째 그림과 제일 가까운 그림? 이렇게 하면 거리가 나와서 이미지간 유사도를 측정할 수 있게 됩니다.

def selectImage(n, m, dists, images):
    image_position = dists[n].argsort()[m]
    image = mh.imread(images[image_position])
    return image

def plotImages(n):
    plt.figure(figsize=(15,5))
    
    plt.subplot(141)
    plt.imshow(selectImage(n,0, dists, images))
    plt.title('Original')
    plt.xticks([])
    plt.yticks([])

    plt.subplot(142)
    plt.imshow(selectImage(n,1, dists, images))
    plt.title('1st simular one')
    plt.xticks([])
    plt.yticks([])

    plt.subplot(143)
    plt.imshow(selectImage(n,2, dists, images))
    plt.title('2nd simular one')
    plt.xticks([])
    plt.yticks([])

    plt.subplot(144)
    plt.imshow(selectImage(n,3, dists, images))
    plt.title('3rd simular one')
    plt.xticks([])
    plt.yticks([])

    plt.show()

그림을 그리기 위한 함수 만들고~ 유사도 측정이 잘 되었는지 실증해보죠~

제일 왼쪽과 가장 유사한 그림이 순서대로 그 옆에 있습니다. 비슷하나요?

서로 비슷하나요^^

나쁘지 않네요...^^ mahotas는 재미있는 결과를 쉽게 잘 보여주네요^^

반응형