2017-07-20 17 views
1

私は、下の画像のように、画像の境界を見つけるためにコードを作成しようとしています。ボーダー画像のセグメンテーション

画像

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    ------------------------------------------------ 
0: . . . . . . . . . . . . . . . . 
1: . . . . . . . . . . . . . . . . 
2: . . . . . . . . . . . . . . . . 
3: . . . . x . . . . . . . . . . . 
4: . . . x . x . . . . x . . . . . 
5: . . x x . . . . . x x x . . . . 
6: . . . x x x x x . x x x x . . . 
7: . . . x x x x x . x x x x . . . 
8: . . . . . x x x x x x x x . . . 
9: . . . . . x x x x x x x x . . . 
10: . . . . . x x x . x x x . . . . 
11: . . . . x . x x x x x . . . . . 
12: . . . x . . . . x x . . . . . . 
13: . . . . . . . . . . . . . . . . 
14: . . . . . . . . . . . . . . . . 
15: . . . . . . . . . . . . . . . . 

私は、この画像の境界であるすべてのXをマークする必要があります。 私は隣人に基づいてそれをしようとしていますが、どのような種類の論理を取るべきか分かりません。 すべての援助を歓迎します。ありがとうございました。

+0

いいえ、リンクとして画像を投稿しないでください。 2回目のロールバック。 –

+3

'.'ネイバーを持つすべての' x'をマークアップします。 –

+0

あるものが上にあり、もう一方が右に、次に下に、そして左にあることを確認する関数を作成します。あなたがすでに持っている機能を使用して、あまりにも角度でドットの機能を作成します。次に、2つのforループを使ってイメージを実行し、@WeatherVaneのように、関数を使用して必要なものをマークします。 – Yonlif

答えて

2

まず、あなたは画像を処理する関数を記述する必要があります。おそらく、イメージは2次元文字配列で表されるため、関数はこの配列に対して反復処理を行う必要があります。画像の各'x'がエッジ上にあるかどうかを決定するために第2の関数を使用することができる。結果は出力配列に格納できます。

is_edge()と呼ばれる第2の関数を書くには、'x'がイメージの端にあることが何を意味するのかを判断する必要があります。最初の試行では、背景ピクセル('.')に隣接している場合は、画像のエッジに前景ピクセルが表示されます。これは良い音が、得られる画像はビット「重」であってもよい。

Image edges (is_edge1): 
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    ------------------------------------------------- 
0: . . . . . . . . . . . . . . . . 
1: . . . . . . . . . . . . . . . . 
2: . . . . . . . . . . . . . . . . 
3: . . . . x . . . . . . . . . . . 
4: . . . x . x . . . . x . . . . . 
5: . . x x . . . . . x x x . . . . 
6: . . . x x x x x . x . x x . . . 
7: . . . x x x . x . x . . x . . . 
8: . . . . . x . x x x . . x . . . 
9: . . . . . x . x x x . x x . . . 
10: . . . . . x x x . x x x . . . . 
11: . . . . x . x x x x x . . . . . 
12: . . . x . . . . x x . . . . . . 
13: . . . . . . . . . . . . . . . . 
14: . . . . . . . . . . . . . . . . 
15: . . . . . . . . . . . . . . . . 

は、ここにいくつかのピクセルが除去されている可能性のある、[5] [10]において、例えば、あります。これが正しくないと思われる場合は、is_edge()の機能を再考することができます。代わりに、前景のピクセルが、そのコーナーの1つにない背景のピクセルに隣接している場合、そのエッジにあるとしたらどうでしょうか?

Image edges (is_edge2): 
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    ------------------------------------------------- 
0: . . . . . . . . . . . . . . . . 
1: . . . . . . . . . . . . . . . . 
2: . . . . . . . . . . . . . . . . 
3: . . . . x . . . . . . . . . . . 
4: . . . x . x . . . . x . . . . . 
5: . . x x . . . . . x . x . . . . 
6: . . . x x x x x . x . . x . . . 
7: . . . x x . . x . x . . x . . . 
8: . . . . . x . . x . . . x . . . 
9: . . . . . x . . x . . . x . . . 
10: . . . . . x . x . x . x . . . . 
11: . . . . x . x x x . x . . . . . 
12: . . . x . . . . x x . . . . . . 
13: . . . . . . . . . . . . . . . . 
14: . . . . . . . . . . . . . . . . 
15: . . . . . . . . . . . . . . . . 

この方法は、いくつかの点で優れているようだが、また、あまりにも多くの内部のピクセルを削除するようだ:これはちょうど見種類の余分なピクセルを削除する必要があります。 [11] [9]のピクセルは削除されていることに注意してください。元の画像から削除しないでください。修正は、前景ピクセルが、そのコーナーの1つにない背景ピクセルに隣接している場合、または反対の対角線のコーナーにある2つの背景ピクセルに隣接している場合、エッジにあると考えることです。

Image edges (is_edge3): 
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    ------------------------------------------------- 
0: . . . . . . . . . . . . . . . . 
1: . . . . . . . . . . . . . . . . 
2: . . . . . . . . . . . . . . . . 
3: . . . . x . . . . . . . . . . . 
4: . . . x . x . . . . x . . . . . 
5: . . x x . . . . . x . x . . . . 
6: . . . x x x x x . x . . x . . . 
7: . . . x x . . x . x . . x . . . 
8: . . . . . x . . x . . . x . . . 
9: . . . . . x . . x . . . x . . . 
10: . . . . . x . x . x . x . . . . 
11: . . . . x . x x x x x . . . . . 
12: . . . x . . . . x x . . . . . . 
13: . . . . . . . . . . . . . . . . 
14: . . . . . . . . . . . . . . . . 
15: . . . . . . . . . . . . . . . . 

これは上記の選択肢の最良とすることができる:これは、[11]の1つとして「ブリッジ」の画素[9]を保存するであろう。しかし、このテストケースを考えてみます。上記の提案の3つの方法の

. . . . . 
. . x . . 
. x x x . 
. . x . . 
. . . . . 

は、唯一の第二は、画像の中心からxを削除します。おそらく1つの方法が場合によってはうまく機能し、別の方法では他の場合にはうまくいくでしょう。あるいはもっと良い方法が必要かもしれません。

ここに、上記の出力を生成するために使用された完全なプログラムがあります。 find_edges()関数は、引数として関数ポインタを取ります。したがって、別のis_edge()関数を簡単に実装し、試行し、比較することができます。私はあなたがこのコードを改善する方法を見つけることができると確信しています。

#include <stdio.h> 

#define IMAGE_SZ 16 

void show_image(char img[][IMAGE_SZ], size_t img_sz); 
void find_edges(char in[][IMAGE_SZ], 
       char out[][IMAGE_SZ], 
       size_t img_sz, 
       int (*is_edge)(size_t, size_t, char [][IMAGE_SZ], size_t)); 
int is_edge1(size_t y, size_t x, char in[][IMAGE_SZ], size_t img_sz); 
int is_edge2(size_t y, size_t x, char in[][IMAGE_SZ], size_t img_sz); 
int is_edge3(size_t y, size_t x, char in[][IMAGE_SZ], size_t img_sz); 

int main(void) 
{ 
    char image_in[IMAGE_SZ][IMAGE_SZ] = { "................", 
              "................", 
              "................", 
              "....x...........", 
              "...x.x....x.....", 
              "..xx.....xxx....", 
              "...xxxxx.xxxx...", 
              "...xxxxx.xxxx...", 
              ".....xxxxxxxx...", 
              ".....xxxxxxxx...", 
              ".....xxx.xxx....", 
              "....x.xxxxx.....", 
              "...x....xx......", 
              "................", 
              "................", 
              "................" }; 

    char edge_out[IMAGE_SZ][IMAGE_SZ]; 

    puts("Input image:"); 
    show_image(image_in, IMAGE_SZ); 

    puts("Image edges (is_edge1):"); 
    find_edges(image_in, edge_out, IMAGE_SZ, is_edge1); 
    show_image(edge_out, IMAGE_SZ); 

    puts("Image edges (is_edge2):"); 
    find_edges(image_in, edge_out, IMAGE_SZ, is_edge2); 
    show_image(edge_out, IMAGE_SZ); 

    puts("Image edges (is_edge3):"); 
    find_edges(image_in, edge_out, IMAGE_SZ, is_edge3); 
    show_image(edge_out, IMAGE_SZ); 

    return 0; 
} 

void show_image(char img[][IMAGE_SZ], size_t img_sz) 
{ 
    /* print top numbers */ 
    printf("%4c", ' '); 
    for (size_t j = 0; j < img_sz; j++) { 
     printf("%-3zu", j); 
    } 
    putchar('\n'); 

    /* print dashes */ 
    printf("%4c", '-'); 
    for (size_t j = 0; j < img_sz; j++) { 
     printf("%3s", "---"); 
    } 
    putchar('\n'); 

    /* print rows */ 
    for (size_t i = 0; i < img_sz; i++) { 
     printf("%2zu: ", i); 
     for (size_t j = 0; j < img_sz; j++) { 
      printf("%-3c", img[i][j]); 
     } 
     putchar('\n'); 
    } 
    putchar('\n'); 
} 

void find_edges(char in[][IMAGE_SZ], 
       char out[][IMAGE_SZ], 
       size_t img_sz, 
       int (*is_edge)(size_t, size_t, char [][IMAGE_SZ], size_t)) 
{ 
    for (size_t i = 0; i < img_sz; i++) { 
     for (size_t j = 0; j < img_sz; j++) { 
      out[i][j] = is_edge(i, j, in, img_sz) ? 'x' : '.'; 
      } 
     } 
} 

/* A pixel is an edge if it is adjacent to a background pixel */ 
int is_edge1(size_t y, size_t x, char in[][IMAGE_SZ], size_t img_sz) 
{ 
    int edge_found = 0; 
    if (in[y][x] == 'x') { 
     size_t y_start = (y == 0 ? 0 : y-1); 
     size_t y_stop = (y == (img_sz-1) ? img_sz-1: y+1); 
     size_t x_start = (x == 0 ? 0 : x-1); 
     size_t x_stop = (x == (img_sz-1) ? img_sz-1 : x+1); 


     for (size_t i = y_start; i <= y_stop; i++) { 
      for (size_t j = x_start; j <= x_stop; j++) { 
       if (in[i][j] == '.') { 
        edge_found = 1; 
        break; 
       } 
      } 
      if (edge_found) { 
       break; 
      } 
     } 
    } 

    return edge_found; 
} 

/* a pixel is an edge if it is adjacent to a background pixel that is 
* not a corner pixel 
*/ 
int is_edge2(size_t y, size_t x, char in[][IMAGE_SZ], size_t img_sz) 
{ 
    int edge_found = 0; 
    if (in[y][x] == 'x') { 
     size_t y_start = (y == 0 ? 0 : y-1); 
     size_t y_stop = (y == (img_sz-1) ? img_sz-1: y+1); 
     size_t x_start = (x == 0 ? 0 : x-1); 
     size_t x_stop = (x == (img_sz-1) ? img_sz-1 : x+1); 

     edge_found = (in[y_start][x] == '.' || 
         in[y][x_start] == '.' || 
         in[y][x_stop] == '.' || 
         in[y_stop][x] == '.'); 
    } 

    return edge_found; 
} 

/* a pixel is an edge if it is adjacent to a background pixel that is 
* not a corner pixel or if it is adjacent to two opposite diagonal 
* corner pixels. 
*/ 
int is_edge3(size_t y, size_t x, char in[][IMAGE_SZ], size_t img_sz) 
{ 
    int edge_found = 0; 
    if (in[y][x] == 'x') { 
     size_t y_start = (y == 0 ? 0 : y-1); 
     size_t y_stop = (y == (img_sz-1) ? img_sz-1: y+1); 
     size_t x_start = (x == 0 ? 0 : x-1); 
     size_t x_stop = (x == (img_sz-1) ? img_sz-1 : x+1); 

     edge_found = (in[y_start][x] == '.' || 
         in[y][x_start] == '.' || 
         in[y][x_stop] == '.' || 
         in[y_stop][x] == '.'); 
     if (edge_found == 0) { 
      edge_found = ((in[y_start][x_start] == '.' && 
          in[y_stop][x_stop] == '.') || 
          (in[y_start][x_stop] == '.' && 
          in[y_stop][x_start] == '.')); 
     } 
    } 

    return edge_found; 
} 
+0

ありがとうございました! 私はこの方法を試してみましょう。私のアルゴリズムは 'x'が '。'に隣接しているかどうかを数えるだけでしたが、この論理を破った2つの点がありました。 – user83807

0

画像のすべてのピクセルをテストすることで、try-allアルゴリズムを使用できます。

例(擬似コード):

for i in 0..15 { 
    for j in 0..15 { 
     if image[i][j] == 'x' { 
      /* test the neighbors */ 
      if (image[i-1][j] == '.' || 
       image[i+1][j] == '.' || 
       image[i][j-1] == '.' || 
       image[i][j+1] == '.') { 

       /* It has a '.' neighbor, so this is a border */ 
       image[i][j] = 'y' /* Mark it */ 
      } 
     } 
    } 
} 
関連する問題