雲をつかむ統計。

確率・統計・機械学習・深層学習を紹介するブログ

サイズの異なる同一広告画像の類似度計算

はじめに

画像サイズの異なる同一広告画像の類似度を計算します。2値化などの処理で、固有のhash化したかったですが、失敗しているのでヒストグラムにして類似度計算します。

コード

  • ライブラリ読み込み
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import numpy as np
  • 画像出力
img1 = Image.open('050691a1f51049c4628acef8c65c453e.jpg')
img1

f:id:Beluuuuuuga:20191104203406j:plain

img2 = Image.open('674173f003d2ff9b7e1cc07e2d4746ce.jpg')
img2

f:id:Beluuuuuuga:20191104203426j:plain

  • 画像サイズ確認
img1_size = img1.size
img2_size = img2.size
print(img1_size, img2_size) #=> (796, 416) (480, 251)
  • 方針: 128*128にresize、グレースケール化、 収縮膨張処理を加えて同一画像を作成
# 画像1枚目
# 入力画像の読み込み
img = cv2.imread("050691a1f51049c4628acef8c65c453e")

#リサイズ
img = cv2.resize(img , (128,128))

# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# 方法2 (OpenCVで実装)      
kernel = np.ones((10, 10), np.uint8)
opening1 = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
opening1 = cv2.morphologyEx(opening1, cv2.MORPH_OPEN, kernel)
opening1 = cv2.morphologyEx(opening1, cv2.MORPH_OPEN, kernel)
# 結果を出力
cv2.imwrite("img1.jpg", opening2)

import cv2
import matplotlib.pyplot as plt
import numpy as np

# 画像を読み込む。
img = cv2.imread("img1.jpg", cv2.IMREAD_GRAYSCALE)

# 1次元ヒストグラムを作成する。
hist1 = cv2.calcHist([img], [0], None, histSize=[256], ranges=[0, 256])
hist1 = hist1.squeeze(axis=-1)

# 描画する。
fig, ax = plt.subplots()
ax.fill_between(np.arange(256), hist1, color="black")
ax.set_xticks([0, 255])
ax.set_xlim([0, 255])
ax.set_xlabel("Pixel Value")

f:id:Beluuuuuuga:20191104204145p:plain

# 画像2枚目
# 入力画像の読み込み
img = cv2.imread("674173f003d2ff9b7e1cc07e2d4746ce")

#リサイズ
img = cv2.resize(img , (128,128))

# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# 方法2 (OpenCVで実装)      
# Opening 収縮 膨張3回
kernel = np.ones((10, 10), np.uint8)
opening2 = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
opening2 = cv2.morphologyEx(opening2, cv2.MORPH_OPEN, kernel)
opening2 = cv2.morphologyEx(opening2, cv2.MORPH_OPEN, kernel)

# 結果を出力
cv2.imwrite("img2.jpg", opening2)

# 画像を読み込む。
img = cv2.imread("img2.jpg", cv2.IMREAD_GRAYSCALE)

# 1次元ヒストグラムを作成する。
hist2 = cv2.calcHist([img], [0], None, histSize=[256], ranges=[0, 256])
hist2 = hist2.squeeze(axis=-1)

# 描画する。
fig, ax = plt.subplots()
ax.fill_between(np.arange(256), hist2, color="black")
ax.set_xticks([0, 255])
ax.set_xlim([0, 255])
ax.set_xlabel("Pixel Value")

f:id:Beluuuuuuga:20191104204206p:plain

# ヒストグラムの類似度計算
similarity = cv2.compareHist(hist1, hist2, 0)
similarity #=> 0.8378211241010926

おわりに

  • 類似度0.83のスコアでした。DB内で検索しようと思うと、勾配のインデックスなど作成すれば良いのでしょうか。とりあえず、今日はここまでです。

参照資料