つまりなにしたの?
大量の画像が手に入ってしまったときに、ファイル名はあまり当てにならず画像をいい感じに並び替えたい時がある。
こんなとき、画像のヒストグラムを使って画像同士の近さ(類似度)を出せばソートしやすいんじゃないかと思って
まずは画像同士の類似度を計算してみた。
画像のヒストグラムについて
ensekitt.hatenablog.com
を使ってヒストグラムを作成し、3色分あるのでRGBの順番につなげたベクトルを今回使うことにした。
おおまかな手順
環境
% python --version Python 3.6.4 % pip freeze opencv-python==3.4.0.12 numpy==1.14.1
コード
import cv2 import numpy as np import matplotlib.pyplot as plt # ヒストグラムを計算する関数(グラフも表示する) def img2hist(img): histrgb = [] color = ['r','g','b'] for i,col in enumerate(color): histrgb.append(cv2.calcHist([img],[i],None,[256],[0,256])) plt.plot(histrgb[i],color = col) plt.show() return histrgb # ケーキの画像を読み込む filename = "CAKE.JPG" img = cv2.imread(filename) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(img) plt.show() # ヒストグラムを計算する histrgb_cake = img2hist(img) # ヒストグラムをつなげたベクトルを作る histarray = np.array(histrgb_cake) histvec_cake = histarray.reshape(histarray.shape[0]*histarray.shape[1], 1) # ケーキと珈琲の画像とカレーの画像を読み込んで同じくベクトルにする filename = "CAKE_with_CAFFEE.JPG" img = cv2.imread(filename) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(img) plt.show() histrgb_cwc = img2hist(img) histarray = np.array(histrgb_cwc) histvec_cwc = histarray.reshape(histarray.shape[0]*histarray.shape[1], 1) filename = "CURRY.JPG" img = cv2.imread(filename) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(img) plt.show() histrgb_curry = img2hist(img) histarray = np.array(histrgb_curry) histvec_curry = histarray.reshape(histarray.shape[0]*histarray.shape[1], 1) # ケーキの画像とケーキと珈琲の画像の比較 print(cv2.compareHist(histvec_cake, histvec_cwc, 0)) # ケーキの画像とカレーの画像の比較 print(cv2.compareHist(histvec_cake, histvec_curry, 0)) # 同じ写真同士の比較 print(cv2.compareHist(histvec_cake, histvec_cake, 0))
結果
# ケーキの画像とケーキと珈琲の画像の比較 cv2.compareHist(histvec_cake, histvec_cwc, 0) -0.13217840935957162 # ケーキの画像とカレーの画像の比較 cv2.compareHist(histvec_cake, histvec_curry, 0) -0.060916866737834856 # 同じ写真同士の比較 cv2.compareHist(histvec_cake, histvec_cake, 0) 1.0
「ケーキ」と「ケーキと珈琲」の方が近くなるはずだったけど、皿の面積とかそのへんの要因が災いして
「カレーとケーキ」のほうが近くなっている。ヒストグラムしか見てないからこういうこともある。
使った画像