import os
import cv2
import pandas as pd
from skimage.metrics import structural_similarity as ssim
from concurrent.futures import ThreadPoolExecutor
# フォルダ内の画像ファイルパスを再帰的に取得する関数
def get_image_files(directory):
image_files = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')):
image_files.append(os.path.join(root, file))
return image_files
# SSIMを計算して類似度スコアを返す関数
def calculate_ssim(image1_path, image2_path):
image1 = cv2.imread(image1_path, cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread(image2_path, cv2.IMREAD_GRAYSCALE)
# 画像サイズが異なる場合にリサイズしてから比較する
if image1.shape != image2.shape:
image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))
similarity_index, _ = ssim(image1, image2, full=True)
return similarity_index
# メイン処理
def compare_images(path1, path2, output_file):
# path1, path2内の画像ファイルを取得
path1_files = get_image_files(path1)
path2_files = get_image_files(path2)
results = []
# 並列化のためThreadPoolExecutorを使用
with ThreadPoolExecutor() as executor:
for p2_file in path2_files:
future_results = []
# 各p2_fileに対して全てのp1_fileとSSIMを計算し、結果を格納
for p1_file in path1_files:
future = executor.submit(calculate_ssim, p1_file, p2_file)
future_results.append((future, p1_file))
# 各SSIM結果を収集し、上位3つのスコアを取得
scores = [(future.result(), p1_file) for future, p1_file in future_results]
scores.sort(reverse=True, key=lambda x: x[0]) # スコア順にソート
top_matches = scores[:3] # 上位3つを取得
for score, best_match in top_matches:
results.append([os.path.relpath(best_match, path1), os.path.relpath(p2_file, path2), score])
# 結果をDataFrameに変換してExcelに出力
df = pd.DataFrame(results, columns=['path1(ファイル名)', 'path2(ファイル名)', '類似度スコア'])
df.to_excel(output_file, index=False)
# 使用例
path1 = 'path_to_folder1' # path1のフォルダパス
path2 = 'path_to_folder2' # path2のフォルダパス
output_file = 'output_comparison_top3.xlsx' # 出力先のExcelファイル
compare_images(path1, path2, output_file)
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme