1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【備忘録】ONNXモデルを使用して画像の類似度を算出

Last updated at Posted at 2024-07-11

はじめに

  • 必要なライブラリをインポート
  • ONNXモデルをロード
  • VectorizeImage メソッドで画像をベクトル化
  • CompareImages メソッドで2つの画像のベクトルを比較し、類似度を計算
  • CosineSimilarity メソッドでコサイン類似度を計算

このコードを使用するには、以下の準備が必要です:

NuGetパッケージマネージャーを使用して、Microsoft.ML.OnnxRuntimeとSystem.Drawing.Commonパッケージをインストールします。
CLIPモデル(または同等の画像ベクトル化モデル)をONNX形式に変換し、path/to/model.onnxに配置します。

Program
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;

class Program
{
    static InferenceSession session;

    static void Main(string[] args)
    {
        // ONNXモデルのロード
        session = new InferenceSession("path/to/model.onnx");

        string imagePath1 = "path/to/image1.jpg";
        string imagePath2 = "path/to/image2.jpg";

        float similarity = CompareImages(imagePath1, imagePath2);
        Console.WriteLine($"画像の類似度: {similarity}");
    }

    static float[] VectorizeImage(string imagePath)
    {
        using (var image = new Bitmap(Image.FromFile(imagePath)))
        {
            // 画像の前処理
            var resizedImage = new Bitmap(image, new Size(224, 224));
            var inputTensor = new DenseTensor<float>(new[] { 1, 3, 224, 224 });

            for (int y = 0; y < 224; y++)
            {
                for (int x = 0; x < 224; x++)
                {
                    var pixel = resizedImage.GetPixel(x, y);
                    inputTensor[0, 0, y, x] = (pixel.R / 255f - 0.485f) / 0.229f;
                    inputTensor[0, 1, y, x] = (pixel.G / 255f - 0.456f) / 0.224f;
                    inputTensor[0, 2, y, x] = (pixel.B / 255f - 0.406f) / 0.225f;
                }
            }

            // モデルの実行
            var inputs = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("input", inputTensor) };
            using (var results = session.Run(inputs))
            {
                return results.First().AsTensor<float>().ToArray();
            }
        }
    }

    static float CompareImages(string imagePath1, string imagePath2)
    {
        var vector1 = VectorizeImage(imagePath1);
        var vector2 = VectorizeImage(imagePath2);

        return CosineSimilarity(vector1, vector2);
    }

    static float CosineSimilarity(float[] v1, float[] v2)
    {
        float dotProduct = 0;
        float magnitude1 = 0;
        float magnitude2 = 0;

        for (int i = 0; i < v1.Length; i++)
        {
            dotProduct += v1[i] * v2[i];
            magnitude1 += v1[i] * v1[i];
            magnitude2 += v2[i] * v2[i];
        }

        magnitude1 = (float)Math.Sqrt(magnitude1);
        magnitude2 = (float)Math.Sqrt(magnitude2);

        if (magnitude1 > 0 && magnitude2 > 0)
        {
            return dotProduct / (magnitude1 * magnitude2);
        }
        else
        {
            return 0;
        }
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?