質問編集履歴
2
プログラムの追記
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
|
-
|
8
|
+
#include <iostream>
|
7
|
-
|
9
|
+
#include <opencv2/opencv.hpp>
|
8
|
-
|
10
|
+
#include <math.h>
|
9
|
-
|
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
|
-
|
87
|
+
#include <iostream>
|
81
|
-
|
88
|
+
#include <opencv2/opencv.hpp>
|
82
|
-
|
89
|
+
#include <math.h>
|
83
|
-
|
90
|
+
#define FILE_NAME "../Debug/a.jpg"
|
84
91
|
|
85
|
-
#define FILE_NAME "../Debug/a.jpg"
|
86
|
-
|
87
92
|
//ウィンドウ名
|
88
|
-
|
93
|
+
#define WINDOW_NAME_INPUT "input"
|
89
|
-
|
94
|
+
#define WINDOW_NAME_OUTPUT "output"
|
90
95
|
|
91
96
|
int main(int argc, const char * argv[]){
|
92
|
-
|
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
|
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<
|
117
|
+
for(int y=0;y<src_img.rows;y++){
|
118
|
-
for(int x=0;x<
|
118
|
+
for(int x=0;x<src_img.cols;x++){
|
119
119
|
//画素値の取得
|
120
|
-
|
120
|
+
val = src_img.at<cv::Vec3b>(y,x);
|
121
|
-
if(val[0]>=
|
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
|
-
|
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,
|
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値とプログラムについての追記
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
|
}
|