見出し画像

画像類似度比較 in Python


概要

このスクリプトは、2つの画像ファイルを比較し、その類似度を計算するPythonプログラムです。ヒストグラム比較と構造的類似性(SSIM)の2つの手法を使用して類似度を算出します。

前提条件

  • Python 3.x

  • 以下のPythonライブラリ:

    • OpenCV (cv2)

    • NumPy

    • scikit-image

これらのライブラリは以下のコマンドでインストールできます。

pip install opencv-python numpy scikit-image

スクリプトの内容

スクリプトは主に以下の機能を提供します。

  • 2つの画像ファイルを読み込む

  • 画像のサイズを調整する

  • グレースケールに変換する

  • ヒストグラムを計算し、比較する

  • SSIM(構造的類似性)を計算する

import cv2
import numpy as np
from skimage.metrics import structural_similarity as ssim

def compare_images(image1_path, image2_path):
    # 画像を読み込む
    img1 = cv2.imread(image1_path)
    img2 = cv2.imread(image2_path)

    # 画像のサイズを揃える
    height = min(img1.shape[0], img2.shape[0])
    width = min(img1.shape[1], img2.shape[1])
    
    img1 = cv2.resize(img1, (width, height))
    img2 = cv2.resize(img2, (width, height))

    # グレースケールに変換
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

    # ヒストグラムを計算
    hist1 = cv2.calcHist([gray1], [0], None, [256], [0, 256])
    hist2 = cv2.calcHist([gray2], [0], None, [256], [0, 256])

    # ヒストグラムを正規化
    cv2.normalize(hist1, hist1, 0, 1, cv2.NORM_MINMAX)
    cv2.normalize(hist2, hist2, 0, 1, cv2.NORM_MINMAX)

    # ヒストグラム比較
    similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)

    # SSIM(構造的類似性)を計算
    ssim_score = ssim(gray1, gray2)

    return similarity, ssim_score

# 使用例
image1_path = 'path/to/image1.jpg'
image2_path = 'path/to/image2.jpg'
hist_similarity, ssim_score = compare_images(image1_path, image2_path)

print(f"ヒストグラム類似度: {hist_similarity:.2f}")
print(f"SSIM スコア: {ssim_score:.2f}")

ヒストグラム比較

ヒストグラム比較は、画像の明度分布の類似性を測定します。現在の実装では、相関係数法(cv2.HISTCMP_CORREL)を使用しています。

  • 値の範囲:-1から1の間

  • 解釈:

    • 1に近いほど:類似度が高い(正の相関が強い)

    • 0に近いほど:無相関(類似性が低い)

    • -1に近いほど:逆相関が強い(逆の傾向を示す)

  • 特徴:

    • 画像の全体的な明度分布を比較するため、細かい構造の違いは無視される

    • 計算が比較的高速

    • 画像の回転や小さな変形に対してある程度ロバスト

SSIM(構造的類似性)

SSIMは画像の構造的な類似性を測定します。輝度、コントラスト、構造の3つの要素を考慮して計算されます。

  • 値の範囲:-1から1の間

  • 解釈:

    • 1に近いほど:類似度が高い(ほぼ同一の画像)

    • 0に近いほど:類似性が低い

    • -1に近いほど:逆の構造を持つ(実際にはまれ)

  • 特徴:

    • 人間の視覚システムに基づいた類似性の測定

    • 局所的な構造の違いを検出可能

    • ノイズ、ぼかし、圧縮アーティファクトなどの影響を評価可能

使用方法

1. スクリプトファイル(例:image_similarity_comparison.py)を作成し、提供されたコードを貼り付けます。

2. スクリプト内の image1_path と image2_path 変数に、比較したい画像ファイルのパスを設定します。

3. コマンドラインからスクリプトを実行します:

python image_similarity_comparison.py

4. 結果が表示されます。ヒストグラム類似度とSSIMスコアが出力されます。

処理の流れ

  1. 2つの画像ファイルを読み込む

  2. 画像のサイズを小さい方に合わせてリサイズ

  3. 画像をグレースケールに変換

  4. 各画像のヒストグラムを計算

  5. ヒストグラムを正規化

  6. ヒストグラム比較を実行

  7. SSIM(構造的類似性)を計算

  8. 結果を返す

注意点

  • 画像ファイルのパスが正しく設定されていることを確認してください。

  • 大きなサイズの画像を処理する場合、メモリ使用量が増加する可能性があります。

  • 画像の形式によっては、追加のライブラリが必要になる場合があります。

トラブルシューティング

  • エラー:ImportError: No module named 'cv2'

    • 解決策:pip install opencv-pythonを実行してOpenCVをインストールしてください。

  • エラー:ImportError: No module named 'skimage'

    • 解決策:pip install scikit-imageを実行してscikit-imageをインストールしてください。

  • エラー:FileNotFoundError: [Errno 2] No such file or directory: 'image1.jpg'

    • 解決策:画像ファイルのパスが正しいことを確認し、必要に応じて絶対パスを使用してください。

おまけ:requests.getで取得した画像データを処理する場合

import cv2
import numpy as np
import requests
from skimage.metrics import structural_similarity as ssim

def compare_images_from_urls(image1_url, image2_url):
    # URLから画像を取得
    def get_image_from_url(url):
        response = requests.get(url)
        image_array = np.frombuffer(response.content, np.uint8)
        return cv2.imdecode(image_array, cv2.IMREAD_COLOR)

    img1 = get_image_from_url(image1_url)
    img2 = get_image_from_url(image2_url)

    # 画像のサイズを揃える
    height = min(img1.shape[0], img2.shape[0])
    width = min(img1.shape[1], img2.shape[1])
    
    img1 = cv2.resize(img1, (width, height))
    img2 = cv2.resize(img2, (width, height))

    # グレースケールに変換
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

    # ヒストグラムを計算
    hist1 = cv2.calcHist([gray1], [0], None, [256], [0, 256])
    hist2 = cv2.calcHist([gray2], [0], None, [256], [0, 256])

    # ヒストグラムを正規化
    cv2.normalize(hist1, hist1, 0, 1, cv2.NORM_MINMAX)
    cv2.normalize(hist2, hist2, 0, 1, cv2.NORM_MINMAX)

    # ヒストグラム比較
    similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)

    # SSIM(構造的類似性)を計算
    ssim_score = ssim(gray1, gray2)

    return similarity, ssim_score

# 使用例
image1_url = 'https://example.com/image1.jpg'
image2_url = 'https://example.com/image2.jpg'
hist_similarity, ssim_score = compare_images_from_urls(image1_url, image2_url)

print(f"ヒストグラム類似度: {hist_similarity:.2f}")
print(f"SSIM スコア: {ssim_score:.2f}")

いいなと思ったら応援しよう!