画像処理の面取り距離変換は、オブジェクトマッチング認識でよく使用されます。アルゴリズムは基本的に、3x3ウィンドウに基づいて各ピクセルの距離値を生成し、距離変換を完了するために2つのステップに分割されます。最初のステップは左上隅から始まり、各ピクセルを左から右にスキャンし、上から下にスキャンし、中央のピクセルXの周りの4ピクセルを検出し、結果として最小距離と位置を節約します。図は次のとおりです。
2番目のステップは、各ピクセルについて、結果として、結果として、隣接するピクセル4、5、6、7の最小距離と位置を検出することです。
これらの2つのステップを完了した後、結果出力は面取り距離変換の結果です。完全な画像面取り距離変換コードの実装は、次の手順に分けることができます。
1.ピクセル配列の初期化、すべての背景色ピクセルの初期距離は無限であり、前景ピクセルの距離は0です。
2。面取り距離変換の最初のステップを開始し、結果を保存します
3.最初のステップの結果に基づいて、面取りの距離変換の2番目のステップを完了する
4.距離変換の結果に従ってすべての異なるグレースケール値を表示して画像を形成します
最終結果は次のように表示されます(左は元の画像を示し、右側はCDT後の結果を示します)
完全なバイナリイメージ透評価距離変換のソースコードは次のとおりです。
パッケージcom.gloomyfish.image.transform; java.awt.colorをインポートします。 java.awt.image.bufferedimageをインポートします。 java.util.arraysをインポートします。 com.gloomyfish.filter.study.abstractbufferedimageopをインポートします。パブリッククラスcdtfilterは、abstractbufferedimageop {private float [] dis;を拡張します。 // nn-distances private int [] pos; // nn-positions、32ビットインデックスプライベートカラーbakcgroundcolor; public cdtfilter(color bgcolor){this.bakcgroundcolor = bgcolor; } @Override public bufferedimageフィルター(bufferedimage src、bufferedimage dest){int width = src.getwidth(); int height = src.getheight(); if(dest == null)dest = createcompatibledestimage(src、null); int [] inpixels = new int [width * height]; pos = new int [width * height]; dis = new float [width * height]; src.getRgb(0、0、幅、高さ、インピクセル、0、幅); //ランダムに生成された距離変換ポイントind index = 0; arrays.fill(dis、float.max_value); int numoffc = 0; for(int row = 0; row <height; row ++){for(int col = 0; col <width; col ++){index = row * width+col; if(inpixels [index]!= bakcgroundcolor.getRgb()){dis [index] = 0; pos [index] = index; numoffc ++; }}} final float d1 = 1;最終フロートD2 =(float)Math.sqrt(d1 * d1 + d1 * d1); System.out.println(numoffc);フロートND、ND_TMP; int i、in、cols、行、最寄りのpixel; // 1 2 3 // 0 I 4 // 7 6 5 //最初のパス:フォワード - > l-> r、tb for(rows = 1; rows <height -1; rows ++){for(cols = 1; cols <width -1; cols ++){for(cols = 1; cols <width -1; cols ++){i = rows * width+cols; nd = dis [i]; toseedpixel = pos [i]; if(nd!= 0){//背景pixels in = i;をスキップします。 in += -1; // 0 if((nd_tmp = d1 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += -width; // 1 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += +1; // 2 if((nd_tmp = d1 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += +1; // 3 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } dis [i] = nd; pos [i] = coistepixel; }}} // 2番目のパス:後方 - > r-> l、bt //最初のパスとまったく同じ、(rows = height-2; rows> = 1; rows-){for(cols = width-2; cols> = 1; cols-){i = rows * width + cols; nd = dis [i]; toseedpixel = pos [i]; if(nd!= 0){in = i; in += +1; // 4 if((nd_tmp = d1 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += +width; // 5 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += -1; // 6 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += -1; // 6 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += -1; // 6 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += -1; // 6 if((nd_tmp = d1 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } in += -1; // 7 if((nd_tmp = d2 + dis [in])<nd){nd = nd_tmp; toseedpixel = pos [in]; } dis [i] = nd; pos [i] = coistepixel; }}} for(int row = 0; row <height; row ++){for(int col = 0; col <width; col ++){index = row * width+col; if(float.max_value!= dis [index]){int gray = clamp((int)(dis [index])); Inpixels [index] =(255 << 24)| (灰色<< 16)| (灰色<< 8)|グレー; }}} setrgb(dest、0、0、width、height、inpixels); DESTを返す; } private int clamp(int i){return i> 255? 255:(i <0?0:i); }}上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。