質問編集履歴

2

プログラムの追記

2020/07/30 02:03

投稿

seriko
seriko

スコア29

test CHANGED
File without changes
test CHANGED
@@ -4,17 +4,21 @@
4
4
 
5
5
 
6
6
 
7
+
8
+
7
9
  以下プログラムです。
8
10
 
9
11
 
10
12
 
13
+  ```C++
14
+
11
-  #include <iostream>
15
+ #include <iostream>
12
-
16
+
13
-  include <opencv2/opencv.hpp>
17
+  #include <opencv2/opencv.hpp>
14
-
18
+
15
-  include <math.h>
19
+  #include <math.h>
16
-
20
+
17
-  define FILE_NAME "../Debug/a.jpg"
21
+  #define FILE_NAME "../Debug/a.jpg"
18
22
 
19
23
 
20
24
 
@@ -140,6 +144,8 @@
140
144
 
141
145
 
142
146
 
147
+ ```
148
+
143
149
 
144
150
 
145
151
  追記↓
@@ -154,127 +160,169 @@
154
160
 
155
161
 
156
162
 
157
-
163
+ さらに追記↓
164
+
158
-
165
+ 編集で追加したプログラムをもう一度書き直してみましたがやはり結果が黒塗りになってしまい、行き詰まっています。
166
+
167
+ 何かアドバイスお願いいたします。
168
+
169
+
170
+
171
+ ```C++
172
+
159
- include <iostream>
173
+ #include <iostream>
160
-
174
+
161
- include <opencv2/opencv.hpp>
175
+ #include <opencv2/opencv.hpp>
162
-
176
+
163
- include <math.h>
177
+ #include <math.h>
164
-
165
- #include <stdio.h>
178
+
166
-
167
-
168
-
169
- define FILE_NAME "../Debug/a.jpg"
179
+ #define FILE_NAME "../Debug/a.jpg"
170
180
 
171
181
 
172
182
 
173
183
  //ウィンドウ名
174
184
 
175
- define WINDOW_NAME_INPUT "input"
185
+ #define WINDOW_NAME_INPUT "input"
176
-
186
+
177
- define WINDOW_NAME_OUTPUT "output"
187
+ #define WINDOW_NAME_OUTPUT "output"
178
188
 
179
189
 
180
190
 
181
191
  int main(int argc, const char * argv[]){
182
192
 
183
- cv::Mat gray_img,bin_img;
193
+
184
-
194
+
185
- double distance,dis_max=0;
195
+ double distance=0,dis_max=0;
186
196
 
187
197
  int max_x,max_y;
188
198
 
199
+ int count = 0;
200
+
201
+ float x_g = 0.0f;
202
+
203
+ float y_g = 0.0f;
204
+
205
+ //画像の入力
206
+
207
+ cv::Mat src_img = cv::imread(FILE_NAME);
208
+
209
+ cv::Vec3b val;
210
+
211
+
212
+
213
+
214
+
215
+ if(src_img.empty()){//入力失敗の場合
216
+
217
+ fprintf(stderr,"Cannot read image file: %s,\n",FILE_NAME);
218
+
219
+ return(-1);
220
+
221
+ }
222
+
223
+
224
+
225
+ //出力画像のメモリ確保
226
+
227
+ cv::Mat dst_img = cv::Mat(src_img.size(),CV_8UC1);
228
+
189
229
 
190
230
 
231
+
232
+
233
+ for(int y=0;y<src_img.rows;y++){
234
+
235
+ for(int x=0;x<src_img.cols;x++){
236
+
191
- //画入力
237
+ //画素値取得
238
+
192
-
239
+ val = src_img.at<cv::Vec3b>(y,x);
240
+
241
+ if(val[0]>=225&&val[0]<=245&&val[1]>=215&&val[1]<=235&&val[2]>=195&&val[2]<=220){//青色の建物を探す
242
+
243
+ //重心の計算
244
+
245
+ count++;
246
+
247
+ x_g += x;
248
+
249
+ y_g += y;
250
+
251
+
252
+
253
+ //重心の計算
254
+
193
- cv::Mat src_img = cv::imread(FILE_NAME,cv::IMREAD_COLOR);
255
+ cv::Point2f mc = cv::Point2f( x_g/count, y_g/count);
194
-
256
+
257
+
258
+
195
- cv::Vec3b val;
259
+ distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
196
-
197
-
198
-
260
+
199
- if(src_img.empty()){//入力失敗の場合
261
+ if(distance>dis_max){//一番遠い距離を探す
200
-
262
+
201
- fprintf(stderr,"Cannot read image file: %s,\n",FILE_NAME);
263
+ dis_max=distance;
264
+
202
-
265
+ max_x=x,
266
+
203
- return(-1);
267
+ max_y=y;
268
+
269
+ }
270
+
271
+ }
272
+
273
+
274
+
275
+ }
204
276
 
205
277
  }
206
278
 
207
-
208
-
209
- //二値画像
210
-
211
- //輝度画像への変換
212
-
213
- cvtColor(src_img,gray_img,cv::COLOR_BGR2GRAY);
214
-
215
- //二値画像の生成
216
-
217
- bin_img.create(gray_img.size(),gray_img.type());
218
-
219
- //二値画像への変換
220
-
221
- threshold(gray_img,bin_img,0,255,cv::THRESH_BINARY);
279
+ printf("%f %d %d",dis_max,max_x,max_y);//確認用
222
-
223
-
224
-
225
- //出力画像のメモリ確保
280
+
226
-
227
- cv::Mat dst_img = cv::Mat(src_img.size(),CV_8UC1);
281
+
228
-
229
-
230
-
231
-
232
-
282
+
233
- for(int y=0;y<bin_img.rows;y++){
283
+ for(int y=0;y<src_img.rows;y++){
234
-
284
+
235
- for(int x=0;x<bin_img.cols;x++){
285
+ for(int x=0;x<src_img.cols;x++){
236
-
237
- //画素値の取得
286
+
238
-
239
- val = bin_img.at<cv::Vec3b>(y,x);
287
+ val = src_img.at<cv::Vec3b>(y,x);
240
-
288
+
241
- if(val[0]>=220&&val[0]<=250&&val[1]>=210&&val[1]<=240&&val[2]>=190&&val[2]<=230){//青色の建物を探す
289
+ if(val[0]>=225&&val[0]<=245&&val[1]>=215&&val[1]<=235&&val[2]>=195&&val[2]<=220){//青色の建物を探す
290
+
242
-
291
+ count++;
292
+
243
-
293
+ x_g += x;
294
+
244
-
295
+ y_g += y;
296
+
245
- //重心の計算
297
+ //重心の計算
246
-
247
- cv::Moments mu = moments(bin_img, false );
298
+
248
-
249
- cv::Point2f mc = cv::Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
299
+ cv::Point2f mc = cv::Point2f( x_g/count, y_g/count);
250
-
300
+
301
+
302
+
251
- distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
303
+ distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
252
-
304
+
253
- if(distance>dis_max){//一番遠い距離を探す
305
+ if(distance==dis_max){//一番遠い距離と一致した場合
254
-
306
+
255
- dis_max=distance;
307
+ dst_img.at<unsigned char>(y,x)=255;//一番遠い青色の建物を表示
256
-
257
- max_x=x;
308
+
258
-
259
- max_y=y;
309
+
260
-
310
+
261
- }
311
+ }
312
+
313
+
314
+
315
+ }
262
316
 
263
317
  }
264
318
 
265
319
  }
266
320
 
267
- }
268
-
269
-
270
-
271
- bin_img.at<unsigned char>(max_y,max_x)=255;//一番遠い青色の建物を表示
272
-
273
321
 
274
322
 
275
323
  cv::imshow(WINDOW_NAME_INPUT,src_img);
276
324
 
277
- cv::imshow(WINDOW_NAME_OUTPUT,bin_img);
325
+ cv::imshow(WINDOW_NAME_OUTPUT,dst_img);
278
326
 
279
327
  cv::waitKey();
280
328
 
@@ -285,3 +333,7 @@
285
333
 
286
334
 
287
335
  }
336
+
337
+
338
+
339
+ ```

1

BGR値とプログラムについての追記

2020/07/30 02:02

投稿

seriko
seriko

スコア29

test CHANGED
File without changes
test CHANGED
@@ -137,3 +137,151 @@
137
137
 
138
138
 
139
139
  }
140
+
141
+
142
+
143
+
144
+
145
+ 追記↓
146
+
147
+
148
+
149
+ 皆様回答ありがとうございます。指摘されております「青色の建物」ですが実際には薄い水色のような色で、ツールを使いRGB値を調べていますのでこちらの値で問題はないです。説明不足で申し訳ございませんでした。
150
+
151
+ そして、皆様の回答を元にプログラムを全体的に書き直してみました。まだ理想の結果にはなっていません・・・
152
+
153
+ 引き続きご教示お願いいたします。
154
+
155
+
156
+
157
+
158
+
159
+ #include <iostream>
160
+
161
+ #include <opencv2/opencv.hpp>
162
+
163
+ #include <math.h>
164
+
165
+ #include <stdio.h>
166
+
167
+
168
+
169
+ #define FILE_NAME "../Debug/a.jpg"
170
+
171
+
172
+
173
+ //ウィンドウ名
174
+
175
+ #define WINDOW_NAME_INPUT "input"
176
+
177
+ #define WINDOW_NAME_OUTPUT "output"
178
+
179
+
180
+
181
+ int main(int argc, const char * argv[]){
182
+
183
+ cv::Mat gray_img,bin_img;
184
+
185
+ double distance,dis_max=0;
186
+
187
+ int max_x,max_y;
188
+
189
+
190
+
191
+ //画像の入力
192
+
193
+ cv::Mat src_img = cv::imread(FILE_NAME,cv::IMREAD_COLOR);
194
+
195
+ cv::Vec3b val;
196
+
197
+
198
+
199
+ if(src_img.empty()){//入力失敗の場合
200
+
201
+ fprintf(stderr,"Cannot read image file: %s,\n",FILE_NAME);
202
+
203
+ return(-1);
204
+
205
+ }
206
+
207
+
208
+
209
+ //二値画像
210
+
211
+ //輝度画像への変換
212
+
213
+ cvtColor(src_img,gray_img,cv::COLOR_BGR2GRAY);
214
+
215
+ //二値画像の生成
216
+
217
+ bin_img.create(gray_img.size(),gray_img.type());
218
+
219
+ //二値画像への変換
220
+
221
+ threshold(gray_img,bin_img,0,255,cv::THRESH_BINARY);
222
+
223
+
224
+
225
+ //出力画像のメモリ確保
226
+
227
+ cv::Mat dst_img = cv::Mat(src_img.size(),CV_8UC1);
228
+
229
+
230
+
231
+
232
+
233
+ for(int y=0;y<bin_img.rows;y++){
234
+
235
+ for(int x=0;x<bin_img.cols;x++){
236
+
237
+ //画素値の取得
238
+
239
+ val = bin_img.at<cv::Vec3b>(y,x);
240
+
241
+ if(val[0]>=220&&val[0]<=250&&val[1]>=210&&val[1]<=240&&val[2]>=190&&val[2]<=230){//青色の建物を探す
242
+
243
+
244
+
245
+ //重心の計算
246
+
247
+ cv::Moments mu = moments(bin_img, false );
248
+
249
+ cv::Point2f mc = cv::Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
250
+
251
+ distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
252
+
253
+ if(distance>dis_max){//一番遠い距離を探す
254
+
255
+ dis_max=distance;
256
+
257
+ max_x=x;
258
+
259
+ max_y=y;
260
+
261
+ }
262
+
263
+ }
264
+
265
+ }
266
+
267
+ }
268
+
269
+
270
+
271
+ bin_img.at<unsigned char>(max_y,max_x)=255;//一番遠い青色の建物を表示
272
+
273
+
274
+
275
+ cv::imshow(WINDOW_NAME_INPUT,src_img);
276
+
277
+ cv::imshow(WINDOW_NAME_OUTPUT,bin_img);
278
+
279
+ cv::waitKey();
280
+
281
+
282
+
283
+ return 0;
284
+
285
+
286
+
287
+ }