본문으로 바로가기

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는 재미있는 결과를 쉽게 잘 보여주네요^^


댓글을 달아 주세요

  1. BlogIcon 핑구야 날자 2018.10.24 07:06 신고

    동일한 이미지를 찾을 때 이용하는 방법이 되겠네요

  2. BlogIcon 북두협객 2018.10.24 07:20 신고

    mahotas을 산업현장이나 기타 다양한 방면으로 활용해도 될 것 같습니다~

  3. BlogIcon 공수래공수거 2018.10.24 10:12 신고

    어떻게 보면 비슷한것 같기도 합니다.
    재미있네요^^

  4. BlogIcon STIMA 2018.10.24 16:36 신고

    이런 기술이 요즘에 다양한 곳에서 활용되고 있는 거죠?
    정말 당장 배워서 사용해 보고 싶다는 생각이 듭니다.

  5. BlogIcon 비키니짐(VKNY GYM) 2018.10.24 16:50 신고

    오~ 동일한 이미지를 필요로할때면
    스마트폰에도 사진첩볼때 이런기능 비슷한게 있나봐요ㅎㅎ

  6. BlogIcon 멜로요우 2018.10.26 13:39 신고

    스마트 검색같은거 할때도 이런기능이 쓰이는거죠? 비슷한거 찾을때 왠지 쓰일듯..ㅋ

  7. 주피터 크러셔 2019.01.31 21:50 신고

    박사님 안녕하세요. 찾다 찾다 도저히 해결이 안되서 댓글로나마 여쭤보니다.
    평소에 파이썬으로 주피터 노트북상에서 데이터 분석/머신러닝 연습을 하는데
    노트북 램을 교체하느라 싹 다 지우고 아나콘다를 다시깔고 이전처럼 주피터를 실행했는데
    탭 완성이 뭔가 불편함이 들더라고요. 예를 들어 이전에는
    data=sns.load_data_set('titanic')
    data.describe()
    라고 코드를 치면 describe() 이 괄호 안에 커서가 있을 때 탭을 누르면 exclude=, include= 이런 인자들이
    네모 박스가 뜨면서 호출 되었는데 계속 abs, all, any 이런 함수?들이 알파벳 순서로 먼저 뜨네요.
    버전이 바껴서 이런건지 아니면 설치에 문제가 있는건지 원인을 모르겠습니다. 아직도 해결이 안되네요ㅠㅠ
    검색을 해봐도 해결책을 찾지 못했습니다. 작업을 계속하다 보면 함수나 메소드 괄호 안에 적용해야 될 인자들을 적용해야 되는데 일일이 쉬프트+탭이나 ?를 치니 시간을 많이 잡아 먹네요. 아신다면 해결책을 알려주세요ㅜ

    • BlogIcon PinkWink 2019.02.02 11:48 신고

      저는 알파벳 한 글자는 치고 탭을 눌러서ㅠㅠ.
      해당 에러가 있는 분들을 간혹 만나는데, 사실 잘 모른답니다ㅠㅠ.
      이런 허접한 답변을 드려 송구하네요ㅠㅠ.