teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

プログラムの追記

2020/07/30 02:03

投稿

seriko
seriko

スコア29

title CHANGED
File without changes
body CHANGED
@@ -1,12 +1,14 @@
1
1
  地図のイラストを読み込み、ある座標(今回は53,463)とこの座標から一番遠い青色に塗られている建物を二値画像で表示するプログラムを作成しています。
2
2
  プログラムを実行してみたところ、真っ黒になってしまいます。何かご教示いただければ幸いです。
3
3
 
4
+
4
5
  以下プログラムです。
5
6
 
7
+  ```C++
6
-  #include <iostream>
8
+ #include <iostream>
7
-  include <opencv2/opencv.hpp>
9
+  #include <opencv2/opencv.hpp>
8
-  include <math.h>
10
+  #include <math.h>
9
-  define FILE_NAME "../Debug/a.jpg"
11
+  #define FILE_NAME "../Debug/a.jpg"
10
12
 
11
13
  //ウィンドウ名
12
14
  #define WINDOW_NAME_INPUT "input"
@@ -69,6 +71,7 @@
69
71
 
70
72
  }
71
73
 
74
+ ```
72
75
 
73
76
  追記↓
74
77
 
@@ -76,69 +79,92 @@
76
79
  そして、皆様の回答を元にプログラムを全体的に書き直してみました。まだ理想の結果にはなっていません・・・
77
80
  引き続きご教示お願いいたします。
78
81
 
82
+ さらに追記↓
83
+ 編集で追加したプログラムをもう一度書き直してみましたがやはり結果が黒塗りになってしまい、行き詰まっています。
84
+ 何かアドバイスお願いいたします。
79
85
 
86
+ ```C++
80
- include <iostream>
87
+ #include <iostream>
81
- include <opencv2/opencv.hpp>
88
+ #include <opencv2/opencv.hpp>
82
- include <math.h>
89
+ #include <math.h>
83
- #include <stdio.h>
90
+ #define FILE_NAME "../Debug/a.jpg"
84
91
 
85
- #define FILE_NAME "../Debug/a.jpg"
86
-
87
92
  //ウィンドウ名
88
- define WINDOW_NAME_INPUT "input"
93
+ #define WINDOW_NAME_INPUT "input"
89
- define WINDOW_NAME_OUTPUT "output"
94
+ #define WINDOW_NAME_OUTPUT "output"
90
95
 
91
96
  int main(int argc, const char * argv[]){
92
- cv::Mat gray_img,bin_img;
97
+
93
- double distance,dis_max=0;
98
+ double distance=0,dis_max=0;
94
99
  int max_x,max_y;
95
-
100
+ int count = 0;
101
+ float x_g = 0.0f;
102
+ float y_g = 0.0f;
96
103
  //画像の入力
97
- cv::Mat src_img = cv::imread(FILE_NAME,cv::IMREAD_COLOR);
104
+ cv::Mat src_img = cv::imread(FILE_NAME);
98
105
  cv::Vec3b val;
99
106
 
107
+
100
108
  if(src_img.empty()){//入力失敗の場合
101
109
  fprintf(stderr,"Cannot read image file: %s,\n",FILE_NAME);
102
110
  return(-1);
103
111
  }
104
112
 
105
- //二値画像
106
- //輝度画像への変換
107
- cvtColor(src_img,gray_img,cv::COLOR_BGR2GRAY);
108
- //二値画像の生成
109
- bin_img.create(gray_img.size(),gray_img.type());
110
- //二値画像への変換
111
- threshold(gray_img,bin_img,0,255,cv::THRESH_BINARY);
112
-
113
113
  //出力画像のメモリ確保
114
114
  cv::Mat dst_img = cv::Mat(src_img.size(),CV_8UC1);
115
-
115
+
116
116
 
117
- for(int y=0;y<bin_img.rows;y++){
117
+ for(int y=0;y<src_img.rows;y++){
118
- for(int x=0;x<bin_img.cols;x++){
118
+ for(int x=0;x<src_img.cols;x++){
119
119
  //画素値の取得
120
- val = bin_img.at<cv::Vec3b>(y,x);
120
+ val = src_img.at<cv::Vec3b>(y,x);
121
- if(val[0]>=220&&val[0]<=250&&val[1]>=210&&val[1]<=240&&val[2]>=190&&val[2]<=230){//青色の建物を探す
121
+ if(val[0]>=225&&val[0]<=245&&val[1]>=215&&val[1]<=235&&val[2]>=195&&val[2]<=220){//青色の建物を探す
122
+ //重心の計算
123
+ count++;
124
+ x_g += x;
125
+ y_g += y;
126
+
127
+ //重心の計算
128
+ cv::Point2f mc = cv::Point2f( x_g/count, y_g/count);
122
129
 
123
- //重心の計算
124
- cv::Moments mu = moments(bin_img, false );
125
- cv::Point2f mc = cv::Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
126
130
  distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
127
131
  if(distance>dis_max){//一番遠い距離を探す
128
132
  dis_max=distance;
129
- max_x=x;
133
+ max_x=x,
130
134
  max_y=y;
131
135
  }
132
136
  }
137
+
133
138
  }
134
139
  }
135
-
140
+ printf("%f %d %d",dis_max,max_x,max_y);//確認用
141
+
142
+ for(int y=0;y<src_img.rows;y++){
143
+ for(int x=0;x<src_img.cols;x++){
144
+ val = src_img.at<cv::Vec3b>(y,x);
145
+ if(val[0]>=225&&val[0]<=245&&val[1]>=215&&val[1]<=235&&val[2]>=195&&val[2]<=220){//青色の建物を探す
146
+ count++;
147
+ x_g += x;
148
+ y_g += y;
149
+ //重心の計算
150
+ cv::Point2f mc = cv::Point2f( x_g/count, y_g/count);
151
+
152
+ distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
153
+ if(distance==dis_max){//一番遠い距離と一致した場合
136
- bin_img.at<unsigned char>(max_y,max_x)=255;//一番遠い青色の建物を表示
154
+ dst_img.at<unsigned char>(y,x)=255;//一番遠い青色の建物を表示
155
+
156
+ }
157
+
158
+ }
159
+ }
160
+ }
137
161
 
138
162
  cv::imshow(WINDOW_NAME_INPUT,src_img);
139
- cv::imshow(WINDOW_NAME_OUTPUT,bin_img);
163
+ cv::imshow(WINDOW_NAME_OUTPUT,dst_img);
140
164
  cv::waitKey();
141
165
 
142
166
  return 0;
143
167
 
144
- }
168
+ }
169
+
170
+ ```

1

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

2020/07/30 02:02

投稿

seriko
seriko

スコア29

title CHANGED
File without changes
body CHANGED
@@ -67,4 +67,78 @@
67
67
 
68
68
  return 0;
69
69
 
70
+ }
71
+
72
+
73
+ 追記↓
74
+
75
+ 皆様回答ありがとうございます。指摘されております「青色の建物」ですが実際には薄い水色のような色で、ツールを使いRGB値を調べていますのでこちらの値で問題はないです。説明不足で申し訳ございませんでした。
76
+ そして、皆様の回答を元にプログラムを全体的に書き直してみました。まだ理想の結果にはなっていません・・・
77
+ 引き続きご教示お願いいたします。
78
+
79
+
80
+ #include <iostream>
81
+ #include <opencv2/opencv.hpp>
82
+ #include <math.h>
83
+ #include <stdio.h>
84
+
85
+ #define FILE_NAME "../Debug/a.jpg"
86
+
87
+ //ウィンドウ名
88
+ #define WINDOW_NAME_INPUT "input"
89
+ #define WINDOW_NAME_OUTPUT "output"
90
+
91
+ int main(int argc, const char * argv[]){
92
+ cv::Mat gray_img,bin_img;
93
+ double distance,dis_max=0;
94
+ int max_x,max_y;
95
+
96
+ //画像の入力
97
+ cv::Mat src_img = cv::imread(FILE_NAME,cv::IMREAD_COLOR);
98
+ cv::Vec3b val;
99
+
100
+ if(src_img.empty()){//入力失敗の場合
101
+ fprintf(stderr,"Cannot read image file: %s,\n",FILE_NAME);
102
+ return(-1);
103
+ }
104
+
105
+ //二値画像
106
+ //輝度画像への変換
107
+ cvtColor(src_img,gray_img,cv::COLOR_BGR2GRAY);
108
+ //二値画像の生成
109
+ bin_img.create(gray_img.size(),gray_img.type());
110
+ //二値画像への変換
111
+ threshold(gray_img,bin_img,0,255,cv::THRESH_BINARY);
112
+
113
+ //出力画像のメモリ確保
114
+ cv::Mat dst_img = cv::Mat(src_img.size(),CV_8UC1);
115
+
116
+
117
+ for(int y=0;y<bin_img.rows;y++){
118
+ for(int x=0;x<bin_img.cols;x++){
119
+ //画素値の取得
120
+ val = bin_img.at<cv::Vec3b>(y,x);
121
+ if(val[0]>=220&&val[0]<=250&&val[1]>=210&&val[1]<=240&&val[2]>=190&&val[2]<=230){//青色の建物を探す
122
+
123
+ //重心の計算
124
+ cv::Moments mu = moments(bin_img, false );
125
+ cv::Point2f mc = cv::Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 );
126
+ distance=sqrt(((463-mc.y)*(463-mc.y))+((mc.x-53)*(mc.x-53)));//座標と建物の距離の計算
127
+ if(distance>dis_max){//一番遠い距離を探す
128
+ dis_max=distance;
129
+ max_x=x;
130
+ max_y=y;
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ bin_img.at<unsigned char>(max_y,max_x)=255;//一番遠い青色の建物を表示
137
+
138
+ cv::imshow(WINDOW_NAME_INPUT,src_img);
139
+ cv::imshow(WINDOW_NAME_OUTPUT,bin_img);
140
+ cv::waitKey();
141
+
142
+ return 0;
143
+
70
144
  }