データ内の画像の重複について(簡易自動化バージョン)

データ内の画像の重複について(簡易自動化バージョン)

Tyanakaiさんが、データ内の画像重複に関するトピックを掲載くださいました。

https://prob.space/competitions/religious_art/discussions/Tyanakai-Post096f62edc542b4902976

このトピックに関連して、類似画像の抽出を簡易自動化したバージョンを掲載いたします。
ご活用ください。

GoogleGoogle Colaboratory にて実行できます。

ライブラリのインストール、インポート

# 画像の重複をチェックするライブラリのインストール(https://github.com/idealo/imagededup)
!pip install imagededup
# 各ライブラリのインポート
import warnings
warnings.simplefilter('ignore')
import numpy as np
from PIL import Image
from pathlib import Path
from imagededup.methods import PHash
from imagededup.utils import plot_duplicates

データの読み込み

# 訓練データ、ラベルデータ、テストデータの保存されたパスを指定
# (環境に合わせて設定してください。)
dataset_path = Path("/content/drive/MyDrive/data")
# 各データファイルのパスを指定
train_image_path = dataset_path / "christ-train-imgs.npz"
train_label_path = dataset_path / "christ-train-labels.npz"
test_image_path = dataset_path / "christ-test-imgs.npz"
# 各データの読み込み
Y_train = np.load(train_label_path)["arr_0"].astype(np.int)
X_train = np.load(train_image_path)["arr_0"].astype(np.float)
test = np.load(test_image_path)["arr_0"].astype(np.float)

初期設定

# 訓練画像、テスト画像を一時的に保存するディレクトリの作成
train_path = Path("train_images")
test_path = Path("test_images")

if not train_path.exists():
    train_path.mkdir()
if not test_path.exists():
    test_path.mkdir()
# 分類するクラス数の設定
num_classes = 13

訓練データの類似画像のチェック

# 類似画像チェック用の画像ファイルの保存
for label in range(num_classes):
    label_index = np.where(Y_train == label)[0]
    for idx, data in enumerate(X_train[label_index]):
        image_path = f'./{train_path}/{label}_{idx}.gif'

        pil_img = Image.fromarray(np.uint8(data))
        pil_img.save(image_path )
# PHashを用いてハッシュ値が類似している画像のチェック
# デフォルトの設定で類似判定しているので、一部類似していない画像もありますが、幅広で抽出しています。
phasher = PHash()
encodings = phasher.encode_images(image_dir=str(train_path))
duplicates = phasher.find_duplicates(encoding_map=encodings)
2021-07-14 05:04:59,967: INFO Start: Calculating hashes...
100%|██████████| 654/654 [00:01<00:00, 576.28it/s]
2021-07-14 05:05:01,197: INFO End: Calculating hashes!
2021-07-14 05:05:01,199: INFO Start: Evaluating hamming distances for getting duplicates
2021-07-14 05:05:01,203: INFO Start: Retrieving duplicates using Cython Brute force algorithm
100%|██████████| 654/654 [00:00<00:00, 72598.85it/s]
2021-07-14 05:05:01,333: INFO End: Retrieving duplicates using Cython Brute force algorithm
2021-07-14 05:05:01,335: INFO End: Evaluating hamming distances for getting duplicates
# PHashを用いたチェック結果の出力
# デフォルトの設定で類似判定しているので、一部類似していない画像もありますが、幅広で抽出しています。
for k, v in duplicates.items():
    if v:
      print(k, v)
      plot_duplicates(image_dir=str(train_path), 
                duplicate_map=duplicates, 
                filename=k)        
5_7.gif ['6_4.gif']
11_28.gif ['11_14.gif']
11_35.gif ['11_2.gif']
4_18.gif ['4_21.gif']
1_36.gif ['1_19.gif']
2_1.gif ['2_12.gif']
2_33.gif ['2_92.gif']
5_38.gif ['5_20.gif']
2_15.gif ['2_29.gif']
4_32.gif ['4_38.gif']
2_68.gif ['2_113.gif']
2_29.gif ['2_15.gif', '11_26.gif']
5_37.gif ['5_17.gif', '5_32.gif']
4_14.gif ['4_11.gif']
2_113.gif ['2_41.gif', '2_68.gif']
1_1.gif ['1_37.gif']
6_4.gif ['5_7.gif']
11_41.gif ['11_6.gif']
5_17.gif ['5_37.gif']
11_2.gif ['11_35.gif']
2_92.gif ['2_33.gif']