LoginSignup
5
11

More than 5 years have passed since last update.

ステーキ定食の画像から物体を選別できないかやってみた - ③類似画像ヒートマップ検出編

Last updated at Posted at 2017-06-13

はじめに

ステーキ定食の画像から物体を選別できないかやってみた - オーバーラップ数編に引き続き、今回はヒストグラム比較をして類似画像の検出を行ってみました。

参考

ソースコード

※ ちょっとリファクタリングしてない箇所ございますが、一旦無視していただければとおもいます。

ちなみに、今回はほぼ同じ画像サイズの矩形を纏めるので、あえて画像のリサイズはしておりません。

group_image.py
# -*- coding: utf-8 -*-

import cv2
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import selectivesearch
import os

def main():
    # loading lena image
    img = cv2.imread("{画像ファイル}")

    # perform selective search
    img_lbl, regions = selectivesearch.selective_search(
        img,
        scale=500,
        sigma=0.9,
        min_size=10
    )

    candidates = set()

    for r in regions:
        # excluding same rectangle (with different segments)
        if r['rect'] in candidates:
            continue

        # excluding regions smaller than 2000 pixels
        if r['size'] < 2000:
            continue

        # distorted rects
        x, y, w, h = r['rect']

        if w / h > 1.2 or h / w > 1.2:
            continue

        candidates.add(r['rect'])

    # draw rectangles on the original image
    fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
    ax.imshow(img)

    overlaps = {}

    # オーバーラップの数をカウントして配列に代入します。
    for x, y, w, h in candidates:
        group = x + y + w + h

        for x2, y2, w2, h2 in candidates:
            if x2 - w < x < x2 + w2 and y2 - h < y < y2 + h2:

                if not group in overlaps:
                    overlaps[group] = 0

                overlaps[group] = overlaps[group] + 1

    # オーバーラップの数が30以上のファイルを出力します(30は勝手に閾値を敷いています)。
    for key, overlap in enumerate(overlaps):
        if overlap > 30:
            for x, y, w, h in candidates:
                group = x + y + w + h

                if group in overlaps:
                    cv2.imwrite("{ファイルパス}" + str(group) + '.jpg', img[y:y + h, x:x + w])

    # ヒストグラム比較をして画像の類似度を算出する
    image_dir = "{ファイルパス}/"
    target_files = os.listdir(image_dir)
    files = os.listdir(image_dir)

    for target_file in target_files:
        if target_file == '.DS_Store':
            continue

        target_image_path = image_dir + target_file
        target_image = cv2.imread(target_image_path)
        target_hist = cv2.calcHist([target_image], [0], None, [256], [0, 256])

        for file in files:
            if file == '.DS_Store' or file == target_file:
                continue

            comparing_image_path = image_dir + file
            comparing_image = cv2.imread(comparing_image_path)
            comparing_hist = cv2.calcHist([comparing_image], [0], None, [256], [0, 256])

            ret = cv2.compareHist(target_hist, comparing_hist, 0)
            probability = ret * 100

            print("target file: " + target_file, "file: " + file, "similarity: " + str(probability) + "%")

if __name__ == "__main__":
    main()

結果

similarityが100%のものがまったく同じ画像みたいです。
※マイナスになってるのもあるけど...

('target file: 1018.jpg', 'file: 250.jpg', 'similarity: 24.8911807562%')
('target file: 1018.jpg', 'file: 369.jpg', 'similarity: 6.78223462382%')
('target file: 1018.jpg', 'file: 389.jpg', 'similarity: 11.1974626968%')
('target file: 1018.jpg', 'file: 432.jpg', 'similarity: 35.179639392%')
('target file: 1018.jpg', 'file: 463.jpg', 'similarity: 79.5281353144%')
('target file: 1018.jpg', 'file: 477.jpg', 'similarity: 51.5870749875%')
('target file: 1018.jpg', 'file: 480.jpg', 'similarity: 55.1832671208%')
('target file: 1018.jpg', 'file: 492.jpg', 'similarity: 88.2822944972%')
('target file: 1018.jpg', 'file: 522.jpg', 'similarity: 76.9528435542%')
('target file: 1018.jpg', 'file: 547.jpg', 'similarity: 84.9997652385%')
('target file: 1018.jpg', 'file: 559.jpg', 'similarity: 77.6441098189%')
('target file: 1018.jpg', 'file: 575.jpg', 'similarity: 76.3571281251%')
('target file: 1018.jpg', 'file: 581.jpg', 'similarity: 76.7456283874%')
('target file: 1018.jpg', 'file: 594.jpg', 'similarity: 31.9957806646%')
('target file: 1018.jpg', 'file: 603.jpg', 'similarity: 85.3813480299%')
('target file: 1018.jpg', 'file: 629.jpg', 'similarity: 88.0957855275%')
('target file: 1018.jpg', 'file: 632.jpg', 'similarity: 60.7236277665%')
('target file: 1018.jpg', 'file: 634.jpg', 'similarity: 62.3073009307%')
('target file: 1018.jpg', 'file: 635.jpg', 'similarity: 65.5935422037%')
('target file: 1018.jpg', 'file: 657.jpg', 'similarity: 56.6421422253%')
('target file: 1018.jpg', 'file: 658.jpg', 'similarity: 82.0967550779%')
('target file: 1018.jpg', 'file: 659.jpg', 'similarity: 89.7396556858%')
('target file: 1018.jpg', 'file: 754.jpg', 'similarity: 78.3236083079%')
('target file: 1018.jpg', 'file: 758.jpg', 'similarity: 79.0903410039%')
('target file: 1018.jpg', 'file: 799.jpg', 'similarity: 89.3025985059%')
('target file: 1018.jpg', 'file: 806.jpg', 'similarity: 97.2873823376%')
('target file: 1018.jpg', 'file: 815.jpg', 'similarity: 93.3345515745%')
('target file: 1018.jpg', 'file: 867.jpg', 'similarity: 81.8261095798%')
('target file: 1018.jpg', 'file: 920.jpg', 'similarity: 93.4987208053%')
('target file: 1018.jpg', 'file: 921.jpg', 'similarity: 90.3518029292%')
('target file: 1018.jpg', 'file: 932.jpg', 'similarity: 94.4258967857%')
('target file: 1018.jpg', 'file: 964.jpg', 'similarity: 10.5652113467%')
('target file: 1018.jpg', 'file: 972.jpg', 'similarity: 98.8755231495%')
---- 以下略

詳細

similarityが90%以上のものはどれくらいなのかというと、

('target file: 1018.jpg', 'file: 972.jpg', 'similarity: 98.8755231495%')

1018.jpg

972.jpg

('target file: 754.jpg', 'file: 758.jpg', 'similarity: 99.8932682258%')

754.jpg

758.jpg

結構上々な精度な気がします。

まとめ

一旦結構良い結果がぱっと見はでたみたいなので、次回は類似度の高い画像をグループ化して纏めたいとおもいます。

全ページリンク

5
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
11