EnsekiTT Blog

EnsekiTTが書くブログです。

OpenCVを使ってヒストグラムの相関で画像同士の近さを計算してみた話

つまりなにしたの?

大量の画像が手に入ってしまったときに、ファイル名はあまり当てにならず画像をいい感じに並び替えたい時がある。
こんなとき、画像のヒストグラムを使って画像同士の近さ(類似度)を出せばソートしやすいんじゃないかと思って
まずは画像同士の類似度を計算してみた。
f:id:ensekitt:20180813204944j:plain

画像のヒストグラムについて

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))

f:id:ensekitt:20180813204720j:plain

結果

# ケーキの画像とケーキと珈琲の画像の比較
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

「ケーキ」と「ケーキと珈琲」の方が近くなるはずだったけど、皿の面積とかそのへんの要因が災いして
「カレーとケーキ」のほうが近くなっている。ヒストグラムしか見てないからこういうこともある。

使った画像

f:id:ensekitt:20180813204906j:plain
f:id:ensekitt:20180813204858j:plain
f:id:ensekitt:20180813204902j:plain

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。