画像のエッジ検出処理について。

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

画像のエッジ検出処理について。

#1

投稿記事 by ホッチ » 6年前

Sobelフィルタを用いた画像のエッジ検出処理を行いたいです。
ソースコードはそのエッジ検出処理部分です。
今詰まっているのが、このままだと2値化されおらず、ぼんやりとしかエッジが検出されません。
そこで、勾配ベクトルの角度を用いて極大値の検出を行い、Res構造体に格納するプログラムを作成したいです。
勾配ベクトルの角度を求めるには、下のソースコードの場合arctan(sumy/sumx)を計算する必要がある所を、actanの計算はせずsumy/sumxの比率のみで45°ずつ区分分けし区分ごとに0,1,2,3,4,5,6,7の番号を振った合計8つに分けることでベクトルの大体の方向を求め、最終的に2値化を行いたいです。
以上の行程をソースコードに埋め込ませたく質問させていただきました。
区分的には(-0.5/1.5=-1/3)< <(0.5/1.5=1/3)が0
1/3< <(1.5/0.5=3)が1となるようにdy/dxの比率で区分けしたいです。

コード:

 
void edge( struct imgptr Img, struct imgptr Res, int h, int w )  //Img=元画,Res=出力構造体,h=元画縦,w=元画横
{
int x, y,i,j;
int sumx,sumy,Ang;
double sumxy,G;

int sobelx[3][3]={{-1,0,1},
                  {-2,0,2},
                  {-1,0,1}};

int sobely[3][3]={{-1,-2,-1},
                  { 0, 0, 0},
                  { 1, 2, 1}};

  for(y=1; y<h-1; y++)
    for(x=1; x<w-1; x++){
      sumx = 0;
      sumy = 0;

      for(j=-1; j<=1; j++)
        for(i=-1; i<=1; i++){
          sumx += Img.w[y+j][x+i] * sobelx[j+1][i+1];   //dx 
          sumy += Img.w[y+j][x+i] * sobely[j+1][i+1];   //dy 
        }
   
      Ang(sumx,sumy);
                
      sumxy = (double)(sumx*sumx + sumy*sumy);         
      G = sqrt( sumxy );                    //勾配ベクトル絶対値
      if(G>10.0)
        Res.w[y][x] = (unsigned char)rint( G/4.0 );    //処理画像に格納
      else
	Res.w[y][x] = 0;	             
    }


Math

Re: 画像のエッジ検出処理について。

#2

投稿記事 by Math » 6年前

Windows10,VS2017Communityで動くようなら全文をコメント付きで提示していただかればテストできるので考えてみますが。(いまのソースでもすぐ分かる人がいるかも知れませんが)...

アバター
usao
記事: 1887
登録日時: 11年前

Re: 画像のエッジ検出処理について。

#3

投稿記事 by usao » 6年前

> 勾配ベクトルの角度を求めるには、下のソースコードの場合arctan(sumy/sumx)を計算する必要がある所を、actanの計算はせずsumy/sumxの比率のみで45°ずつ区分分けし区分ごとに0,1,2,3,4,5,6,7の番号を振った合計8つに分けることでベクトルの大体の方向を求め

そこまで具体的にやることが決まってるなら,そこはその通りに書けば良いのではないかと思います.


・上記,「勾配方向を8方向に離散化する話」
・極大値の検出 (何の値に関する,どんな範囲での極大値?)
・最終的に2値化 (方法は?)

なる,各要素間の具体的な関連性がわかりません.


> 質問させていただきました。

質問が存在するように見えません.

返信

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