質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

4272閲覧

C言語 ガウシアンフィルターのソースコードについて

BASEBALL-Y

総合スコア67

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/04/23 03:48

#質問内容
C言語で,ガウシアンフィルターのソースコードを書いているのですが,なぜ,以下の処理を行っているのかが理解できません.

分かる方がいらっしゃいましたら,教えて頂けると幸いです.
##ガウスフィルターで用いた公式
イメージ説明

##質問箇所のコード

C

1y = i + k - size / 2; 2x = j + l - size / 2; 3 4k_y = k - size / 2; 5k_x = l - size / 2;

#全体のコード

C

1void GaussianFilter(unsigned char gray_img[Y_SIZE][X_SIZE], unsigned char gauss_img[Y_SIZE][X_SIZE], int size, double sigma) 2{ 3 int i, j, k, l, x, y; 4 int k_x, k_y; 5 6 double mask; 7 double gauss_mask; 8 double PI = 3.141592; 9 double gauss_const = 1.0 / (2.0*PI*sigma*sigma); 10 double sum_weight; 11 12 13 for (i = 0; i < Y_SIZE; i++) 14 { 15 for (j = 0; j < X_SIZE; j++) 16 { 17 //初期化 18 gauss_mask = 0; 19 mask = 0; 20 sum_weight = 0; 21 22 for (k = 0; k < size;k++) 23 { 24 for (l = 0; l < size; l++) 25 { 26 y = i + k - size / 2; 27 x = j + l - size / 2; 28 29 k_y = k - size / 2; 30 k_x = l - size / 2; 31 32 //端処理 33 if ((y >= 0 && y < Y_SIZE) && (x >= 0 && x < X_SIZE)) 34 { 35 mask = gauss_const * exp(-(((k_y)*(k_y)+(k_x)*(k_x)) / (2 * sigma*sigma))); 36 //画素位置(j,i)の計算に用いたmaskの総和を計算 37 sum_weight += mask; 38 39 //gray_img[y][x]は輝度値 40 gauss_mask += gray_img[y][x] * mask; 41 } 42 else 43 { 44 gauss_mask += 0; 45 } 46 } 47 } 48 49 50 if (gauss_mask >= 0) 51 { 52 //平滑化後の値を代入(正規化) 53 gauss_img[i][j] = gauss_mask / sum_weight; 54 } 55 else 56 { 57 gauss_img[i][j] = 0; 58 } 59 } 60 } 61}

#参考資料
ガウシアンフィルターのソースコード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

y = i + k - size / 2;
x = j + l - size / 2;

単純にフィルタリング(畳み込み)のために用いる画素の座標(x,y)を求めるだけに見えますが,何が疑問点でしょうか?
(画素位置(j,i)の結果を計算するために参照する入力画像の範囲 に関して考えれば,
x座標の範囲は i-フィルタ半径~i+フィルタ半径 でしょう.y座標の範囲も同様.)

k_y = k - size / 2;
k_x = l - size / 2;

ごれはガウシアンカーネルの中心を(0,0)とする座標系での上記画素の位置ですね.

両者共に,後段でこれらの値を使っている箇所を見れば意味がわかるでしょう.

投稿2020/04/23 03:56

編集2020/04/23 03:58
fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/04/23 04:05

話が単純化…されるかどうか微妙ですが, ガウシアンではなくて,例えば,【位置(x,y)の出力画素値を,(x,y)を中心とする3x3範囲の入力画素値の平均値とする】単純な平滑化フィルタについて考えてみてはどうでしょう. (「(x,y)を中心とする3x3範囲の入力画素値の平均値」を求めるために,「まず総和を求めて,次にそれを9で割る」としよう.→まずは総和を求めるのを2重ループで書くとして,そのループ内で参照すべき画素の座標ってのは…)
BASEBALL-Y

2020/05/05 07:19

すみません.ベストアンサーを決めてからで申し訳ないのですが,なぜ,ガウシアンカーネルの中心を(0,0)にする必要があるのでしょうか? (0,0)にすると言うことは,つまり,k_xとk_yは0になるということでしょうか?
fana

2020/05/05 09:16

別に計算さえできればどうやってもいいでしょうけども…… expのところを計算するのに「カーネル中心からどれくらい離れてるか」が必要になるでしょうから, どうやってもカーネル中心が(0,0)になるような世界に一旦持っていくんじゃないでしょうか.
BASEBALL-Y

2020/05/06 02:12

fanaさん! 回答にお時間を割いて頂き,本当にありがとうございます. 自分自身,勉強不足でした・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問