広告

【OpenCvSharp】画像の特徴点と類似度を取得

OpenCV

当サイトではアフィリエイト広告を利用しています。

広告

はじめに

今回は、OpenCvSharpを使用して、画像の特徴点類似度を取得してみます。

全く同じ画像かどうかの比較ではなく、似ているかどうかを判定してみます。
画像に対して特徴量を取得し、比較するやり方です。

OpenCvSharpのインストールや、サンプルアプリの作成は以下の記事を参考にしてください。

【C#】OpenCVSharpで画像処理!【Visual Studio 2022】
OpenCVを利用した画像処理を行ってみましょう。C#でOpenCVSharpを使って基本的な操作例から、実用的な実装例をまとめました。

Visual Studio 2022のインストールにつきましては、以下の記事にまとめましたので参考ください。

Visual Studio 2022のインストールとサンプルアプリ作成
C#で、Windowsアプリを作成してみます。手始めに準備として、インストール手順をまとめてみました。
使用するバージョン
  • Windows 11 / 10
  • Visual Studio 2022 (2019)

他にも私のブログで、OpenCVについて解説している記事がありますのでご覧ください。

画像の特徴点の検出

まずは画像を用意します。
以下のフリー素材を使用しました。

猫 ねこ ネコ 猫アップ 猫の顔
猫 大きい目が可愛いトラ猫のアップ(No: 4085695)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材としてお…

私は以下の場所に画像を保存しました。

D:\project\img\cat1.jpg

画像の特徴点をAKAZEを使用して、検出してみます。

特徴点を検出するアルゴリズムは、SURFSIFTなどがあります。

フォームにボタンを配置し、クリックイベントに以下のように実装しました。

private void button9_Click(object sender, EventArgs e)
{
    using (var mat = new Mat(@"D:\project\img\cat1.jpg"))
    using (var descriptors = new Mat())
    using (var drowKeyPoint = new Mat())
    {
        var akaze = AKAZE.Create();

        // キーポイントを検出
        akaze.DetectAndCompute(mat, null, out KeyPoint[] keyPoints, descriptors);

        // 画像に描画
        Cv2.DrawKeypoints(mat, keyPoints, drowKeyPoint);
        Cv2.ImShow("image", drowKeyPoint);
    }
}

keyPointsについては、outパラメーター修飾子で参照渡しにし、検出結果を受け取っています。

実行してみると、以下のように画像の特徴点を取得することができました。

広告

画像の類似度の取得

比較1

次に、画像の類似度を取得してみます。
先程抽出した、画像の特徴点同士のマッチングを行い、類似度を取得します。

比較対象として、先程の画像と似ている、以下のフリー素材を使用しました。

見つめるトラ猫の可愛いアップ猫画像
猫 ねこ 見つめるトラ猫の可愛いアップ (No: 4085698)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材と…

私は以下の場所に画像を保存しました。

D:\project\img\cat2.jpg

今回は特徴量のマッチングとして、BFMatcher(Brute Force)を使用しました。
その名の通り、総当たりです。

他にもFlannBasedMatcherなどがあります。

実用的に使用できるように関数を作成しました。
引数に、比較したい画像を2つ指定します。
また、比較結果の画像を表示するかどうかのフラグを設けました。

/// <summary>
/// 2つの画像の類似度をチェックする
/// </summary>
/// <param name="mat1"></param>
/// <param name="mat2"></param>
/// <param name="show">画像を表示するかのフラグ</param>
/// <returns></returns>
private float ImageMatch(Mat mat1, Mat mat2, bool show)
{

    using (var descriptors1 = new Mat())
    using (var descriptors2 = new Mat())
    {

        // 特徴点を検出
        var akaze = AKAZE.Create();

        // キーポイントを検出
        akaze.DetectAndCompute(mat1, null, out KeyPoint[] keyPoints1, descriptors1);
        akaze.DetectAndCompute(mat2, null, out KeyPoint[] keyPoints2, descriptors2);

        // それぞれの特徴量をマッチング
        var matcher = new BFMatcher(NormTypes.Hamming, false);
        var matches = matcher.Match(descriptors1, descriptors2);

        // 2つの画像のマッチング結果を表示
        if (show)
        {
            using (var drowMatch = new Mat())
            {
                Cv2.DrawMatches(mat1, keyPoints1, mat2, keyPoints2, matches, drowMatch);
                Cv2.ImShow("image match", drowMatch);
            }
        }

        // 平均距離を返却(小さい方が類似度が高い)
        var sum = matches.Sum(x => x.Distance);
        return sum / matches.Length;

    }

}

類似度として、特徴量マッチングの距離の平均を取得しました。
全く同じであれば0であり、値が小さいほど、画像は似ていることになります。

呼び出し方は以下です。

private void button8_Click(object sender, EventArgs e)
{
    using (var mat1 = new Mat(@"D:\project\img\cat1.jpg"))
    using (var mat2 = new Mat(@"D:\project\img\cat2.jpg"))
    {
        // 2つの画像を比較(平均距離をスコアとした)
        float score = ImageMatch(mat1, mat2, true);
        Console.WriteLine("score:" + score);
    }
}	

実行してみた結果は以下です。
左右に二枚の画像が配置しており、それぞれの特徴量を線で引いています。

スコアは以下になりました。(コンソールに出力されています)

score:100.8207

比較2

折角なので、もう一枚比較してみましょう。

バーニーズマウンテンドッグ
バーニーズマウンテンドッグ(No: 4207210)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材としてお使いくだ…

比較結果は以下です。

スコアは先程よりは少し上がりました。
先程の猫同士のほうが似ていることになりますね。

score:121.8167

さいごに

今回は画像の類似度を求めてみました。
OpenCvSharpで簡単にできるので、ぜひ試してみてくださいね?

他にも私のブログで、OpenCVについて解説している記事がありますのでご覧ください。

C#OpenCVOSWindowsプログラミング作ってみよう
広告

個人開発

千草 @chigusaweb

現役のITエンジニア。 気ままにコードを書いたり技術情報を発信しています。 Webアプリ/Windows・Macアプリ/モバイルアプリなど。 (Java, PHP, Javascript, Swift, Python, C#, 他) 個人開発:Clibor, Quipha, TXT-Crypter, 符計算特訓, チグサツール Kindle本: Laravel9 実践入門, 他

クリップボード履歴

Clibor

Windows

Cliborはシンプルで高機能なクリップボード履歴ソフトです。 また普段よく使うワードを定型文として登録し、いつでもクリップボードに保存することができます。高度なテキスト整形・FIFOモード・ホットキーに対応。

クリップボード履歴

Windows版Cliborの利便性を、そのままMacでも。 定型文登録、高度なテキスト整形、FIFOモードなど、便利なクリップボード履歴機能を利用できます。macOS最新のTahoeにも対応。

テキスト暗号化

テキストを暗号化してURLで共有・保存できる無料サービスです。 パスフレーズを知る人だけが復号できます。登録不要、データはサーバーに保存されません。 Notionでも利用できます。

学習

Quipha

Web / iOS

自分だけの問題集や問題を作成し、クイズを行い、学習に活用することができるアプリです。 例えば、学校の授業、語学学習、IT資格やその他の資格など多彩な分野での学習を支援します。 いつでも、どこでも、あなたの学習をサポート。

ツール

日常の「ちょっとした効率化」をサポートするWeb便利ツール集。 テキスト・データ処理から最新のAI連携まで、日々のちょっとした手間でググりがちなユーティリティを1つの場所に集約。

麻雀

麻雀の符計算をひたすら特訓しマスターしましょう。 初心者の方はもちろん、もっと速く計算したい方にも役立ちます。 5万対局以上の実践から問題を収録。

コメント

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