ファイル名が異なる同じ画像を特定したい!

ノウハウ
スポンサーリンク

スマホで撮影した写真をPCに保管したとき、自動でリネームされてしまい、どれが同じ写真か分からなくなってしまいました。。。そのため、同じ画像を特定するツールをPythonで作りました。

PythonさえPCに入っていれば簡単に利用できますので、ご参考にどうぞ。
Pythonなんて入っていないよって方向けに、補足でPythonの導入方法で分かりやすそうなサイトをまとめたので、この機会に導入してみてはいかがでしょうか。

 

目次

 


 

使用するPythonライブラリ

使用するPythonライブラリは以下の4つです。

  • glob
    • 画像ファイルを検索するのに使用します。
    • Python 標準ライブラリに含まれているため、特にインストールは不要です。
  • hashlib
    • ハッシュ値を計算するのに使用します。
    • Python 標準ライブラリに含まれているため、特にインストールは不要です。
    • 「同じデータをハッシュ関数にかけると同じハッシュ値になる」というハッシュ値の特性を利用して、同じファイルかどうかの判定にハッシュ値を使用します。
  • pandas
    • 重複するハッシュ値がないか検索するために使用します。
    • Python 標準ライブラリに含まれていないため、インストールが必要です。
  • os
    • ファルダかファイルかを判断するために使用します。
    • Python 標準ライブラリに含まれているため、特にインストールは不要です。

  

「pandas」のインストールは以下のコマンドでできます。

> pip install pandas

  

 

Pythonのサンプルコード

ファイル名が異なる同じ画像を特定するサンプルコードを以下に張っておきます。
(MITライセンスとします。)

import glob, hashlib, os
import pandas as pd

##### パラメータ指定
# 画像ファイルを検索するフォルダを指定
TARGET_DIRS = {
    'C:/work/sample/sample1',
    'C:/work/sample/sample2',
}
# アウトプットファイルの格納先を指定
OUTPUT_DIR = 'C:/work'

##### 初期処理
# アウトプットファイルの設定
outputFile = open(OUTPUT_DIR + '/output.txt', mode='w', encoding = "utf_8")

##### ハッシュcsv用のdataframeを作成
column = ['filepath' , 'hash']
data = []
for targetDir in TARGET_DIRS:
    for targetFilePath in glob.glob(targetDir+'/**', recursive=True):
        # ファイル以外は飛ばす
        if not os.path.isfile(targetFilePath): continue
        # ハッシュ値計算
        with open(targetFilePath, 'rb') as f:
            targetHash = hashlib.sha256(f.read()).hexdigest()  
        data.append([targetFilePath, targetHash])

df = pd.DataFrame(data, columns=column)

##### ハッシュの重複チェック
is_duplicated = df.duplicated(subset = "hash")
if( is_duplicated.any() ):
    # duplicated()は初回の重複行はFalseになるが、それ以降の重複行はすべてTrueになるため、
    # df_tmpには重複したhash値が複数含まれている。
    df_tmp = df[is_duplicated]

    # 重複したhash値を1つのみ抽出して一覧化するため、さらにduplicated()を実行する。
    df_duplicated_hashes = df_tmp[~df_tmp.duplicated(subset = "hash")]

    # 重複したhash値を持つファイル = 同じファイルと考えてよいので、
    # 重複したhash値ごとに紐づいたファイルを出力する。
    for row in df_duplicated_hashes.itertuples():
        # コンソールとアウトプットファイルへ出力
        print('===== 重複したファイルを検出 =====')
        print('以下のファイルは重複しています。')
        outputFile.write('===== 重複したファイルを検出 =====\n')
        outputFile.write('以下のファイルは重複しています。\n')
        for row in df[df['hash'] == row.hash].itertuples():
            # 重複したファイルを表示する
            print(row.filepath)
            outputFile.write(row.filepath + '\n')
else:
    # 重複なし
    print('重複したファイルはありませんでした。')
    outputFile.write('重複したファイルはありませんでした。\n')

##### 終了処理
outputFile.close()
  • TARGET_DIRSで画像ファイルが格納されたフォルダを指定してください。配下のフォルダは再帰的に検索します。
  • OUTPUT_DIRで結果を記載するテキストの格納先を指定します。

 

 

サンプルコードを試してみる

簡単なテスト環境でサンプルコードを実行してみました。

 

テスト環境

テスト環境は以下を想定します。

 

【ディレクトリ構成】

Cドライブ配下にworkフォルダを作成し、その配下のsampleに画像ファイルを格納しています。
「DuplicatedImageChecker.py」には上記サンプルコードが記載されています。

C:\WORK
│  DuplicatedImageChecker.py
│
└─sample
    ├─sample1
    │      cat_icon1.png
    │      cat_icon2.png
    │      cat_pic1.jpg
    │      cat_pic2.jpg
    │
    └─sample2
            cat_pic1.jpg
            cat_pic2.jpg
            cat_smile.png
            kitten.jpg

 

【画像ファイル】

  • 「sample/sample1/cat_icon1.png」と「sample/sample2/cat_smile.png」、「sample/sample1/cat_pinc1.jpg」と「sample/sample2/kitten.jpg」は同じファイルですが、ファイル名はあえて異なるようにしています。
  • 「sample/sample1/cat_pinc1.jpg」と「sample/sample2/at_pinc1.jpg」、「sample/sample1/cat_pinc2.jpg」と「sample/sample2/at_pinc2.jpg」は異なるファイルですが、ファイル名は同じにしています。

 

サンプルコードの実行

コマンドプロンプトで以下のコマンドを実行します。

> cd C:\work
> python DuplicatedImageChecker.py

 

サンプルコード実行結果

C:\work>python DuplicatedImageChecker.py
===== 重複したファイルを検出 =====
以下のファイルは重複しています。
C:/work/sample/sample1\cat_icon1.png
C:/work/sample/sample2\cat_smile.png
===== 重複したファイルを検出 =====
以下のファイルは重複しています。
C:/work/sample/sample1\cat_pic1.jpg
C:/work/sample/sample2\kitten.jpg
  • 同じファイルである「sample/sample1/cat_icon1.png」と「sample/sample2/cat_smile.png」、「sample/sample1/cat_pinc1.jpg」と「sample/sample2/kitten.jpg」を検出することができています。
  • 同じファイル名ですが、異なるファイルである「sample/sample1/cat_pinc1.jpg」と「sample/sample2/at_pinc1.jpg」、「sample/sample1/cat_pinc2.jpg」と「sample/sample2/at_pinc2.jpg」は別のファイルとして検出されています。(別ファイルのため、画面上には表示されていません。)

 

期待通り、ファイル名が異なる同じ画像を特定することができています!

 

 

補足 Pythonをインストールするのに参考になりそうなサイト

日本のPythonコミュニティ「python.jp」さんのサイトが、画像で説明されており分かりやすいです。

Windows版Pythonのインストール - python.jp
以下の手順で、Pythonのインストールを行います。 Python公式サイトから、Pythonパッケージをダウンロードします ダウンロードしたパッケージをインストールします。 PowerShellでPythonを実行するときに必要となる、ス...

 

広告

Pythonを勉強するなら、Udemyの「現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル」がオススメです!
※Udemyは技術的な講座を動画で受けられるサービスです。

 

以上!

コメント

タイトルとURLをコピーしました