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

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

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

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

Q&A

解決済

2回答

1615閲覧

C言語 ラベリングについて

BASEBALL-Y

総合スコア67

C

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

0グッド

0クリップ

投稿2020/06/02 13:07

##質問内容
4近傍のラベリングを実装したいと思っているのですが,0と1しか表示されません.

本来は,

0,1,2,3,4,・・・

といったように,順次,ラベル数を足していきたいです.

##コード

C

1//------------------------------------------- 2//r_in,g_in,b_in・・・入力画像 3//r_out_labeling,g_out_labeling,b_out_labeling・・・出力画像 4// 5//------------------------------------------- 6//ラベリングを行うための関数(https://gist.github.com/masazdream/8630805) 7void labeling(unsigned char r_in[Y_SIZE][X_SIZE], unsigned char g_in[Y_SIZE][X_SIZE], unsigned char b_in[Y_SIZE][X_SIZE], unsigned char r_out_labeling[Y_SIZE][X_SIZE], unsigned char g_out_labeling[Y_SIZE][X_SIZE], unsigned char b_out_labeling[Y_SIZE][X_SIZE]) 8{ 9 int i, j; 10 11 int up_r, up_g, up_b; 12 int left_r, left_g, left_b; 13 14 int up_r_label, up_g_label, up_b_label; 15 int left_r_label, left_g_label, left_b_label; 16 17 unsigned char r_out[Y_SIZE][X_SIZE]; 18 unsigned char g_out[Y_SIZE][X_SIZE]; 19 unsigned char b_out[Y_SIZE][X_SIZE]; 20 21 22 //バッファを作成 23 for (j = 0; j < Y_SIZE; j++) 24 { 25 for (i = 0; i < X_SIZE; i++) 26 { 27 //出力用のrgb値を用意 28 r_out[j][i] = r_in[j][i]; 29 g_out[j][i] = g_in[j][i]; 30 b_out[j][i] = b_in[j][i]; 31 } 32 } 33 34 for (j = 0; j < Y_SIZE; j++) 35 { 36 for (i = 0; i < X_SIZE; i++) 37 { 38 //上の画素(元画像) 39 up_r = r_out[j - 1][i]; 40 up_g = g_out[j - 1][i]; 41 up_b = b_out[j - 1][i]; 42 43 44 //左の画素(元画像) 45 left_r = r_out[j][i - 1]; 46 left_g = g_out[j][i - 1]; 47 left_b = b_out[j][i - 1]; 48 } 49 } 50 51 52 for (j = 0; j < Y_SIZE; j++) 53 { 54 for (i = 0; i < X_SIZE; i++) 55 { 56 57 //ラベル用 58 r_out_labeling[j][i] = r_out[j][i]; 59 g_out_labeling[j][i] = g_out[j][i]; 60 b_out_labeling[j][i] = b_out[j][i]; 61 62 63 //(i,j)が127以下の時・・・ 64 if (r_out[j][i] < 127 && g_out[j][i] < 127 && b_out[j][i] < 127) 65 { 66 //ラベルの値を0にする 67 r_out_labeling[j][i] = 0; 68 g_out_labeling[j][i] = 0; 69 b_out_labeling[j][i] = 0; 70 } 71 //(i,j)が127より大きい時・・・ 72 else if (r_out[j][i] >= 127 && g_out[j][i] >= 127 && b_out[j][i] >= 127) 73 { 74 //ラベルの値を1にする 75 r_out_labeling[j][i] = 1; 76 g_out_labeling[j][i] = 1; 77 b_out_labeling[j][i] = 1; 78 } 79 } 80 } 81 82 for (j = 0; j < Y_SIZE; j++) 83 { 84 for (i = 0; i < X_SIZE; i++) 85 { 86 //上の画素(ラベル) 87 up_r_label = r_out_labeling[j - 1][i]; 88 up_g_label = g_out_labeling[j - 1][i]; 89 up_b_label = b_out_labeling[j - 1][i]; 90 91 92 //左の画素(ラベル) 93 left_r_label = r_out_labeling[j][i - 1]; 94 left_g_label = g_out_labeling[j][i - 1]; 95 left_b_label = b_out_labeling[j][i - 1]; 96 97 98 //注目画素の上と左の値が0の時・・・ 99 if (r_out_labeling[j][i] == 0 && g_out_labeling[j][i] == 0 && b_out_labeling[j][i] == 0) 100 { 101 //続ける 102 continue; 103 } 104 105 //注目画素のラベルが1以上なら・・・ 106 else if (r_out_labeling[j][i] >= 1 && g_out_labeling[j][i] >= 1 && b_out_labeling[j][i] >= 1) 107 { 108 //上と左のラベルが0の時・・・ 109 if ((up_r_label == 0 && up_g_label == 0 && up_b_label == 0) && (left_r_label == 0 && left_g_label == 0 && left_b_label == 0)) 110 { 111 //ラベルに+1する 112 r_out_labeling[j][i] = r_out_labeling[j][i] + 1; 113 g_out_labeling[j][i] = g_out_labeling[j][i] + 1; 114 b_out_labeling[j][i] = b_out_labeling[j][i] + 1; 115 } 116 117 //上か左のラベルが0と0以上の時・・・ 118 if ((up_r_label >= 1 && up_g_label >= 1 && up_b_label >= 1) && (left_r_label == 0 && left_g_label == 0 && left_b_label == 0)) 119 { 120 //0ではない方の値をとる 121 r_out_labeling[j][i] = up_r_label; 122 g_out_labeling[j][i] = up_g_label; 123 b_out_labeling[j][i] = up_b_label; 124 125 } 126 else if ((up_r_label == 0 && up_g_label == 0 && up_b_label == 0) && (left_r_label >= 1 && left_g_label >= 1 && left_b_label >= 1)) 127 { 128 r_out_labeling[j][i] = left_r_label; 129 g_out_labeling[j][i] = left_g_label; 130 b_out_labeling[j][i] = left_b_label; 131 } 132 133 //0以外でラベルが付いている時・・・ 134 if ((up_r_label >= 1 && up_g_label >= 1 && up_b_label >= 1) && (left_r_label >= 1 && left_g_label >= 1 && left_b_label >= 1)) 135 { 136 //もし,上のラベルの方が小さい時・・・ 137 if ((up_r_label < left_r_label) && (up_g_label < left_g_label) && (up_b_label < left_b_label)) 138 { 139 //0ではない方の値をとる 140 r_out_labeling[j][i] = up_r_label; 141 g_out_labeling[j][i] = up_g_label; 142 b_out_labeling[j][i] = up_b_label; 143 144 //大きい方の値を小さい方の値にする 145 left_r_label = up_r_label; 146 left_g_label = up_g_label; 147 left_b_label = up_b_label; 148 } 149 else if ((up_r_label > left_r_label) && (up_g_label > left_g_label) && (up_b_label > left_b_label)) 150 { 151 r_out_labeling[j][i] = left_r_label; 152 g_out_labeling[j][i] = left_g_label; 153 b_out_labeling[j][i] = left_b_label; 154 155 //大きい方の値を小さい方の値にする 156 up_r_label = left_r_label; 157 up_g_label = left_g_label; 158 up_b_label = left_b_label; 159 } 160 //label_upとlabel_leftが同じ値の時・・・ 161 else if ((up_r_label == left_r_label) && (up_g_label == left_g_label) && (up_b_label == left_b_label)) 162 { 163 r_out_labeling[j][i] = up_r_label = left_r_label; 164 g_out_labeling[j][i] = up_g_label = left_g_label; 165 b_out_labeling[j][i] = up_b_label = left_b_label; 166 } 167 } 168 } 169 } 170 } 171 172 173}

ちなみに,ピクセル数をヒストグラムで表すと,以下のような結果になり,0と1しか表示されません.
イメージ説明

##参考資料
ラベリングのアルゴリズムについて

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

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

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

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

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

guest

回答2

0

ベストアンサー

単独で動くコードではないようなので、見たところ、、、

まず、 RGB (3色?) を処理しようとしてますが、分かりにくくなってません?
その一方、127 を閾値にして、判定を行っていますが、全てがどちらかの場合と、混じった場合の処理が混在。 まず、この辺の意図は?

2つ目のfor()で、up_r, up_g, up_b に値を設定してますが、ループ最後の値しか設定されません。なんの意味があるでしょう? もっともその後、使われていないようですが。
.. おっと、ここで、j - 1 の参照。 j=0の場合、不正な値の参照となります。その後の for()でも同じようなところがあります。 (i-iもある)

*_out_labeling に初期値を与えるループがあるようですが、初期値とは思えません。何を設定してるのでしょうか? ここでは、0/1 しか設定してないようなので、それが出力を 0/1 にしてる理由と思われます。 (他の値も設定してるが、それは消える?)

と、、色々と見直し箇所が多そう、、と言うより、単色にしてまずは、0/1のモノクロデータでの検証をお勧めします。

投稿2020/06/04 12:22

pepperleaf

総合スコア6385

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

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

0

こういう規模のコードを書くなら、デバッグできる環境を整えましょう
WindowsならVisualStudioやEclipseなど。
コードを途中で止めて、変数のナカミを見ることができます。
また、1行づつ実行させてコードの実行順や変数の変化を見れるようになります

そうすれば、コードを当てずっぽで組むことがなくなり、どこがまずいのかわからない、と丸投げするようなことはしなくて済むようになります

投稿2020/06/02 14:03

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問