画像処理について。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
らんえぼ

画像処理について。

#1

投稿記事 by らんえぼ » 18年前

こんにちわ。いつもお世話になってます!

質問させてください。

8近傍ラプラシアンフィルタを用いて輪郭が強調された画像にする問題です!

途中までは出来たんですが。。こんな感じです!

int MASK[3][3]={ {1, 1, 1},
{1, -8, 1},
{1, 1, 1}};
int k,l;
for(j=1;j<YSIZE-1;j++){
for(i=1;i<XSIZE-1;i++){

for(l=0;l<3;l++){
for(k=0;k<3;k++){
r2[j]+=(r1[i+k-1][j+l-1]*MASK[k][[/url]);
g2[j]+=(g1[i+k-1][j+l-1]*MASK[k][[/url]);
b2[j]+=(b1[i+k-1][j+l-1]*MASK[k][[/url]);
}
}

たぶんここまではあってると思います。。

このあとに、階調値が255を超える場合は255、0未満の場合は0に変更する

処理を加えるらしいのですがどうもうまくいきません。

分かる方教えてください!


ちなみに元のプログラムはこれです。

int MASK[3][3]={ {1, 1, 1},
{1, -8, 1},
{1, 1, 1}};
int k,l;
for(j=1;j<YSIZE-1;j++){
for(i=1;i<XSIZE-1;i++){
r2[j]=r1[j];
g2[j]=g1[j];
b2[j]=b1[j];
}
}

asd

Re:画像処理について。

#2

投稿記事 by asd » 18年前

>処理を加えるらしいのですがどうもうまくいきません。

どの様にやろうとして失敗しているのですか?

あと、階調値云々の前にRGB画像のままフィルタをかけようとしてませんか?
せめてグレースケール化してからエッジ強調するのが通常だと思いますが・・・。
(RGBそれぞれにマスク演算をするとめちゃくちゃな色になる気がします)

r2、g2、b2それぞれの計算が全て終わった後、再度全体を走査していき、255を超えていたら255に、0より小さかったら0にするfor文を入れればいいだけの気がしますが・・・。

#コンパイル可能なソースを貼り付けてもらえると検証がしやすいかと思います。
#現状ではRGBのままなのか256階調グレースケール画像なのかも分からないので、
#適切なアドバイスが出来ていないかもです。

らんえぼ

Re:画像処理について。

#3

投稿記事 by らんえぼ » 18年前

for文を使うのですか?
自分はこうやったのですが。


int MASK[3][3]={ {1, 1, 1},
{1, -8, 1},
{1, 1, 1}};
int k,l;
for(j=1;j<YSIZE-1;j++){
for(i=1;i<XSIZE-1;i++){

for(l=0;l<3;l++){
for(k=0;k<3;k++){
r2[j]+=(r1[i+k-1][j+l-1]*MASK[k][[/url]);
g2[j]+=(g1[i+k-1][j+l-1]*MASK[k][[/url]);
b2[j]+=(b1[i+k-1][j+l-1]*MASK[k][[/url]);
}
}

if(r2>=255)
r2=255;
if(g2>=255)
g2=255;
if(b2>=255)
b2=255;

if(r2<=0)
r2=0;
if(g2<=0)
g2=0;
if(b2<=0)
b2=0;
}
}

こんな感じでやりました。

asd

Re:画像処理について。

#4

投稿記事 by asd » 18年前

>for(j=1;j<YSIZE-1;j++){
>  for(i=1;i<XSIZE-1;i++){
>
>    for(l=0;l<3;l++){
>      for(k=0;k<3;k++){
>        r2[j]+=(r1[i+k-1][j+l-1]*MASK[k][[/url]);
>        g2[j]+=(g1[i+k-1][j+l-1]*MASK[k][[/url]);
>        b2[j]+=(b1[i+k-1][j+l-1]*MASK[k][[/url]);
>      }
>    }
>  }
>}


この書き方からするとr1、g1、b1、r2、g2、b2は画像のピクセルデータが入っている二次元配列だと
考えられます。
もうちょっと分かりやすくすると例えば、5*5ピクセルの画像があったとしましょう
(□、■1つがピクセル1つだと思ってください)

□□■□□
□■■□□
□□■□□
□□■□□
□■■■□

で、これを読み込むとこういう配列になると思います。

r1[/url][/url] = {
  {255,255,  0,255,255},
  {255,  0,  0,255,255},
  {255,255,  0,255,255},
  {255,255,  0,255,255},
  {255,  0,  0,  0,255},
}

一応白と黒ピクセルのみなのでg1、b1も同じ値になると思ってください(白黒以外のカラーだとそれぞれ別になります)
で、ここにフィルタをかけていくのでそれぞれのピクセルの値が変化します(正しくフィルタをかけた結果じゃないです)

r2[/url][/url] = {
  {<u>356</u>,<u>342</u>, <u>-4</u>, 42,<u>320</u>},
  {230, <u>-5</u>, <u>-5</u>,135,168},
  {255, 23, <u>-6</u>,185,<u>541</u>},
  {145,255,  0,165,255},
  { <u>-2</u>,  0, <u>-4</u>,  0,255},
}


このまま画像として表示しようとすると不具合がおきます。
基本的にRGBの値(ピクセル)は0~255の範囲となっているので、
それぞれのデータの内、負の値になっているところと、255を超えているところをそれぞれ強制的に0と255に置き換えます(下線部を書き換えます)

r2[/url][/url] = {
  {<u>255</u>,<u>255</u>,  <u>0</u>, 42,<u>255</u>},
  {230,  <u>0</u>,  <u>0</u>,135,168},
  {255, 23,  <u>0</u>,185,<u>255</u>},
  {145,255,  0,165,255},
  {  <u>0</u>,  0,  <u>0</u>,  0,255},
}


ですので配列の要素を見てあげないといけません。
int MASK[3][3]={ {1, 1, 1},
                 {1, -8, 1},
                 {1, 1, 1}};
int k,l;
for(j=1;j<YSIZE-1;j++){
  for(i=1;i<XSIZE-1;i++){
    for(l=0;l<3;l++){
      for(k=0;k<3;k++){
        r2[j]+=(r1[i+k-1][j+l-1]*MASK[k][[/url]);
        g2[j]+=(g1[i+k-1][j+l-1]*MASK[k][[/url]);
        b2[j]+=(b1[i+k-1][j+l-1]*MASK[k][[/url]);
      }
    }
  }
}

/*ピクセル値を0~255の範囲に*/
for(j=1;j<YSIZE-1;j++){
  for(i=1;i<XSIZE-1;i++){
    if(r2[j] > 255) r2[j] = 255;
    if(g2[j] > 255) g2[j] = 255;
    if(b2[i][j] > 255) b2[i][j] = 255;
    if(r2[i][j] < 0) r2[i][j] = 0;
    if(g2[i][j] < 0) g2[i][j] = 0;
    if(b2[i][j] < 0) b2[i][j] = 0;
  }
}


こんな感じでしょうか。

ちなみに、
>r2=255;
とすると配列のポインタを操作することになるのでそのままアクセスしようとすると場合によってはプログラムが落ちるかもです。

分かりにくかったり、何か勘違いをしていたらゴメンナサイ。

閉鎖

“C言語何でも質問掲示板” へ戻る