• ベストアンサー

背景差分法における正規化距離

tomochin630の回答

  • ベストアンサー
回答No.1

文字数制限で書ききれないので、2回に分けて投稿します。 以下は差分抽出関数です。 簡単のため、エラーチェックは省いてます。 //img … 検査画像のBITMAP構造体 //bg … 背景画像のBITMAP構造体 void Diff(BITMAP img, BITMAP bg) {  const int bw = 5;//局所領域のサイズ  const int br = bw/2;//局所領域の中心から見た±方向の領域上限  int w = img.bmWidth;//画像幅  int h = img.bmHeight;//画像高さ  unsigned char* buf = GetGrayscaleBytesFromBitmap(img);//検査画像のグレースケール取得  unsigned char* bgimg = GetGrayscaleBytesFromBitmap(bg);//背景画像のグレースケール取得  float* vector1 = (float*)malloc(sizeof(float)*bw*bw);//検査画像の局所領域バッファ  float* vector2 = (float*)malloc(sizeof(float)*bw*bw);//背景画像の局所領域バッファ  //局所領域が画像内に収まるように、上下左右にbrだけ「のりしろ」を入れる。  for(int y=br;y<h-br;y++){   for(int x=br;x<w-br;x++){    //検査画像と背景画像の局所領域グレー値をvector1とvector2に格納する。    //ついでにvector1とvector2の距離を求めておく。    float vectorAbs1=0.0; //vector1の距離(2乗和を求めて最後に√する)    float vectorAbs2=0.0; //vector2の距離(2乗和を求めて最後に√する)    for(int dy=-br;dy<=br;dy++){     for(int dx-br;dx<=br;dx++){      int idx_vct = (dy+br)*bw + (dx+br);//局所領域バッファの格納順番(左上→右下)      int idx_img = (y+dy)*w + (x+dx);//グレースケール配列の格納順番(左上→右下)      vector1[idx_vct]=(float)buf[idx_img];//検査画像のグレー値を格納      vector2[idx_vct]=(float)bgimg[idx_img];//背景画像のグレー値を格納      vectorAbs1 += vector1[idx_vct]*vector1[idx_vct];      vectorAbs2 += vector2[idx_vct]*vector2[idx_vct];     }    }    vectorAbs1 = sqrt(vectorAbs1);//√して距離にする    vectorAbs2 = sqrt(vectorAbs2);//√して距離にする    //格納された局所領域のグレー値から、正規化距離による差分を計算する。    float distance = 0.0; //差分(2乗和を求めて最後に√する)    for(int dy=-br;dy<=br;dy++){     for(int dx-br;dx<=br;dx++){      int idx_vct = (dy+br)*bw + (dx+br);//局所領域バッファの格納順番(左上→右下)      float dif = vector1[idx_vct]/vectorAbs1 - vector2[idx_vct]/vectorAbs2;      diffSq += dif*dif;     }    }    distance = sqrt(distance);//√して距離にする    //差分が閾値より大きければ検査画像の画素を赤で塗りつぶす    int idx_img32 = (y*w + x)*4; //検査画像のピクセルバッファ位置(1画素=4バイト)    img.bmBits[idx_img32] = 255; //赤=255    img.bmBits[idx_img32+1] = 0; //緑=0    img.bmBits[idx_img32+2] = 0; //青=0   }  }  //バッファ解放  free(buf);  free(bgimg);  free(vector1);  free(vector2); }

noname#260977
質問者

お礼

ありがとうございました。 思っていた通りの処理ができましたっ!^^/

関連するQ&A

  • アニメの背景の一部に3DCGを使うメリットは?

    こんにちは。 最近のアニメで『イノセンス』等のように背景の一部に3DCGを使う理由は何なのでしょうか? 他の疑問として3Dに見えるのは、なめらかな影を付けているからですか? 静止画のトゥーンレンダリングが3Dに見える理由は?

  • C#で疑似カラー

    C#のWindowsアプリケーションでボタン一つでグレースケール画像に疑似カラーを付けるプログラムが作りたいのですが、疑似カラーを付けるプログラムをどのように組めばいいのかわかりません。 ここのサイトに載ってある疑似カラーのルールにしたがって作ればいいって言われてるのですが。。。↓ http://imagingsolution.blog107.fc2.com/blog-entry-171.html どなたか教えていただけないでしょうか。

  • CSSで背景画像に指定されている画像を抽出して、グレースケールに変換っ

    CSSで背景画像に指定されている画像を抽出して、グレースケールに変換って可能でしょうか?できれば、JavaScriptで行いたいのですが、もし、グレースケールに変換方法をご存知の方がいればご教授いただけないでしょうか? また、JavaScriptで無理ならば、どの言語ならば可能かも教えていただければ幸いです。知識が無くて誠に申し訳ございません。

  • 画像の背景を透明に

    スキャナーした自筆のメモをvideopadの静止画に、メモの背景を透明にして文字だけを挿入したく、苦労しています。 windows8を使用。 今まで試したこと (1)ペイントにスキャナーした画像を貼り付けて「gif」で保存し、再度呼び出し「選択」から「透明の選択」を指定。これは綺麗に透明にならずすりガラスのようになります。 (2)Wordで「背景の削除」。これは画像全てが選択されて、背景だけを消しことはできません。 (3)Wordで「色」→「透明色を指定」これも、きめの粗いグレーになる。 (4)Wordで「色の変更」→白にして保存→ペイントに挿入しようと思ったが、拡張子が変えられず挿入できない。

  • 画像を拡大したときに背景表示させるには

    ホームページ作成の中で、静止画を拡大したいとき、 クリックするとポップアップ画像で拡大画像を表示 させることは出来るのですが、このときに背景に グレーで網をかけ、クリックする前の画面を表示させる のはどのようにするのでしょうか。 http://www.au.kddi.com/seihin/ichiran/cdma1x_win/xmini/index.html こちらのメイン携帯をクリックしたときのイメージです。 Flashで作り込まないと出来ないのでしょうか。 よろしくお願いいたします。

  • プログラミングについてです。お願いします。

    動画と静止画をうまい具合につなげたいのです。UNIXでC言語を使ってプログラミングしなくてはいけないのですが全く分かりません。誰か教えてください。お願いします。

  • 最適なプログラム言語は?

    パソコンアプリケーションで以下のことをおこないますが開発言語は何が最適でしょうか? 1.静止画(jpg)や音声ファイルを扱う 2.タッチパネル(rs232c) 3.無線タグ(rs232c) つまり 静止画の案内をみながら画面をタッチして外部のタグの読み書きをおこなうようなアプリです。 扱う静止画や音声はかなりの量があります。

  • 3DS MAXによる実写との合成

    3DS MAX初心者です。おもに動画の質問なのですが、合成するには、Compositを使わなければならないのでしょうか?それを使うには、MAXのどのメニューから進めばよいのでしょうか? その際の、動画や、レンダリングしたデータの拡張子などは決められているのでしょうか? また、その際に、影などは反映されるでしょうか?静止画時点で、実写の背景に影を入れる方法が分かりません。というか、レンダリングに関して、背景を実写の画像にするぐらいしか知識が無いので、詳しい方、是非ご教授いただきたいです。

  • C言語 極座標変換

    C言語で画像を極座標変換するソースコードをおしえていただけないでしょうか。512*512 32bitグレースケール(float)画像です。C初心者なので難しくて困っています。よろしくおねがいいたします。

  • C++/CLIのDLLを、C#で参照した際の変数型

    現在、C++/CLIで作成したDLLを、C#で使おうとしています。 http://xptn.dtiblog.com/blog-entry-20.html 上記サイトを参考に、DLLを参照することはできたのですが、 C++/CLI側で「ulong」で定義した引数が、 C#で参照したとき「uint」に変わってしまっています。 【C++/CLI】  opensession(ULONG arg1, ULONG* arg2 ); 【C#】  opensession(UINT arg1, UINT* arg2); 調べてはいるのですが、 この原因がどうしてもわかりません。 ご教授のほど、よろしくお願いします。