ImageMagickをビルドして画像比較APIをCのソースから呼ぶまで

ImageMagick の準備

GitHub - ImageMagick/ImageMagick-Windows: Windows build of ImageMagick 7

上記のリポジトリを取ってくる。

README に依存関係とかちゃんと書いてくれてるのでその通りに Visual Studio をインストール。

CloneRepositories.IM7.cmd を実行

Configure.sln を開いてビルド。 Configure.exe っていうのが Configure フォルダにできる。

Configure.exe を実行すると、ImageMagickのソリューションを設定するためのツールが立ち上がる。自分の環境に合わせて設定する。私の場合は OpenCLは不要だったのと、静的ライブラリが欲しかったのでそちらにチェックした。

実行すると、リポジトリのルートにソリューションファイルが出来上がる。

ソリューションを開いてビルドすると、 Artifacts/lib に静的ライブラリができる。

利用側ソースコード

何でもいいので、VIsual StudioC++ のソリューションを作成。

ソリューションのプロパティを開いて

C/C++」→「全般」→「追加のインクルードディレクトリ」に ImageMagickリポジトリの「ImageMagickディレクトリを指定。

また、「リンカー」→「入力」→「追加の依存ファイル」に先ほどビルドした *.lib ファイルを全部突っ込む。

#include <stdio.h>
#include <MagickWand/MagickWand.h>

int main(int argc, char** argv)
{
    // ImageMagick環境の初期化
    MagickWandGenesis();

    // MagickWandの作成
    MagickWand* image1_wand = NULL;
    MagickWand* image2_wand = NULL;
    MagickWand* diff_wand = NULL;
    double distortion;

    // 画像を処理するためのMagickWandを作成
    image1_wand = NewMagickWand();
    image2_wand = NewMagickWand();
    diff_wand = NewMagickWand();

    // 入力画像を読み込む
    if (MagickReadImage(image1_wand, "C:\\Users\\bamch\\Downloads\\expected.png") == MagickFalse) {
        fprintf(stderr, "画像1の読み込みに失敗しました\n");
        return 1;
    }

    if (MagickReadImage(image2_wand, "C:\\Users\\bamch\\Downloads\\compare.png") == MagickFalse) {
        fprintf(stderr, "画像2の読み込みに失敗しました\n");
        return 1;
    }

    MagickSetImageFuzz(image1_wand, 1.0);
    MagickSetImageFuzz(image2_wand, 1.0);

    diff_wand = MagickCompareImages(image1_wand, image2_wand, AbsoluteErrorMetric, &distortion);

    // 画像比較を行い、差分を取得
    if (diff_wand == 0) {
        fprintf(stderr, "画像の比較に失敗しました\n");
        return 1;
    }

    // 差分を保存する
    if (MagickWriteImage(diff_wand, "C:\\Users\\bamch\\Downloads\\difference.png") == MagickFalse) {
        fprintf(stderr, "差分画像の保存に失敗しました\n");
        return 1;
    }

    // 画像間の歪み(類似度)を出力
    printf("画像間の歪み: %f\n", distortion);

    // リソースの解放
    image1_wand = DestroyMagickWand(image1_wand);
    image2_wand = DestroyMagickWand(image2_wand);
    diff_wand = DestroyMagickWand(diff_wand);

    // ImageMagick環境のクリーンアップ
    MagickWandTerminus();

    printf("画像比較が完了しました\n");
    return 0;
}

こんな感じでソースをかいてビルドしたら、完了。

Magick++ の場合

Magick++ の場合のコードはこんな感じ。

加えて、インクルードディレクトリに ImageMagickリポジトリImageMagick\Magick++\lib を足すこと。

#include <Magick++.h>
#include <iostream>

using namespace Magick;
using namespace std;

int main(int argc, char** argv)
{
    // ImageMagick環境の初期化
    InitializeMagick(*argv);

    // 入力画像をロード
    Image image1;
    Image image2;
    try {
        image1.read("expected.png");
        image2.read("compare.png");
    }
    catch (Exception& error) {
        cout << "画像の読み込みに失敗しました: " << error.what() << endl;
        return 1;
    }

    // ファジネスを設定 (色の微小な違いを無視)
    double fuzz_percentage = 10.0; // 10%のファジネス
    image1.colorFuzz(fuzz_percentage * QuantumRange / 100.0);
    image2.colorFuzz(fuzz_percentage * QuantumRange / 100.0);

    // 歪みのメトリック (類似度) を計算し、差分画像を作成
    double distortion = 0.0;
    Image diff_image;
    try {
        diff_image = image1.compare(image2, AbsoluteErrorMetric, &distortion);
        diff_image.write("difference.png");
    }
    catch (Exception& error) {
        cout << "画像の比較に失敗しました: " << error.what() << endl;
        return 1;
    }

    // 歪み度を出力
    cout << "画像間の歪み (類似度): " << distortion << endl;
    cout << "差分画像を 'difference.png' に保存しました。" << endl;

    return 0;
}