スマホで撮影した写真を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は技術的な講座を動画で受けられるサービスです。
以上!
コメント