回答編集履歴
7
mainについてコメント追加 getMatchPointsの無駄なメソッド呼び出しを改善
test
CHANGED
@@ -66,10 +66,18 @@
|
|
66
66
|
|
67
67
|
|
68
68
|
|
69
|
+
//書き込み
|
70
|
+
|
69
|
-
Imgcodecs.imwrite("out.png", avem2);
|
71
|
+
//Imgcodecs.imwrite("out.png", avem2);
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
//画素値250以上のpointを取得してsetに代入
|
70
76
|
|
71
77
|
Set<IntPoint> s=getMatchPoints(avem2,c->c>(byte)250);//255*0.98
|
72
78
|
|
79
|
+
//出力
|
80
|
+
|
73
81
|
s.forEach(System.out::println);
|
74
82
|
|
75
83
|
}
|
@@ -80,7 +88,7 @@
|
|
80
88
|
|
81
89
|
* @param avem2 グレースケールあるいは二値画像
|
82
90
|
|
83
|
-
* @param tester
|
91
|
+
* @param tester 条件 ちなみに画素値が渡されてくる
|
84
92
|
|
85
93
|
* @return 条件を満たした座標のデータ
|
86
94
|
|
@@ -92,7 +100,7 @@
|
|
92
100
|
|
93
101
|
int height=avem2.height();
|
94
102
|
|
95
|
-
byte [] data =new byte[
|
103
|
+
byte [] data =new byte[width*height];
|
96
104
|
|
97
105
|
avem2.get(0,0,data);
|
98
106
|
|
6
ファイル名の抜け修正
test
CHANGED
@@ -186,7 +186,7 @@
|
|
186
186
|
|
187
187
|
```
|
188
188
|
|
189
|
-
|
189
|
+
__BytePredicate.java__
|
190
190
|
|
191
191
|
```java
|
192
192
|
|
5
バグ修正
test
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
__Q103546.java__
|
2
|
+
|
1
3
|
```java
|
2
4
|
|
3
5
|
package tsukka.teratail.questions.q103546;
|
@@ -8,8 +10,6 @@
|
|
8
10
|
|
9
11
|
import java.util.Set;
|
10
12
|
|
11
|
-
import java.util.function.IntPredicate;
|
12
|
-
|
13
13
|
import org.opencv.core.Core;
|
14
14
|
|
15
15
|
import org.opencv.core.CvType;
|
@@ -22,6 +22,8 @@
|
|
22
22
|
|
23
23
|
import org.opencv.imgproc.Imgproc;
|
24
24
|
|
25
|
+
import tsukka.utility.function.BytePredicate;
|
26
|
+
|
25
27
|
|
26
28
|
|
27
29
|
/**
|
@@ -80,22 +82,22 @@
|
|
80
82
|
|
81
83
|
* @param tester
|
82
84
|
|
83
|
-
* @return
|
85
|
+
* @return 条件を満たした座標のデータ
|
84
86
|
|
85
87
|
*/
|
86
88
|
|
87
|
-
public static Set<IntPoint> getMatchPoints(Mat avem2,
|
89
|
+
public static Set<IntPoint> getMatchPoints(Mat avem2,BytePredicate tester){
|
90
|
+
|
91
|
+
int width=avem2.width();
|
92
|
+
|
93
|
+
int height=avem2.height();
|
88
94
|
|
89
95
|
byte [] data =new byte[avem2.width()*avem2.height()];
|
90
96
|
|
97
|
+
avem2.get(0,0,data);
|
98
|
+
|
91
99
|
HashSet<IntPoint> ret=new HashSet<>();
|
92
100
|
|
93
|
-
avem2.get(0,0,data);
|
94
|
-
|
95
|
-
int width=avem2.width();
|
96
|
-
|
97
|
-
int height=avem2.height();
|
98
|
-
|
99
101
|
for(int y=0;y<height;y++) {
|
100
102
|
|
101
103
|
for (int x = 0; x < width; x++) {
|
@@ -114,38 +116,120 @@
|
|
114
116
|
|
115
117
|
}
|
116
118
|
|
117
|
-
|
119
|
+
|
118
|
-
|
119
|
-
public int x,y;
|
120
|
-
|
121
|
-
public IntPoint(int x,int y){
|
122
|
-
|
123
|
-
this.x=x;
|
124
|
-
|
125
|
-
this.y=y;
|
126
|
-
|
127
|
-
}
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
@Override
|
132
|
-
|
133
|
-
public String toString() {
|
134
|
-
|
135
|
-
return '(' + Integer.toString(x) + ',' + Integer.toString(y) + ')';
|
136
|
-
|
137
|
-
}
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
}
|
142
120
|
|
143
121
|
}
|
144
122
|
|
145
|
-
|
146
|
-
|
147
123
|
```
|
148
124
|
|
125
|
+
|
126
|
+
|
127
|
+
__IntPoint.java__
|
128
|
+
|
129
|
+
```java
|
130
|
+
|
131
|
+
package tsukka.teratail.questions.q103546;
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
import org.opencv.core.Point;
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
/**
|
140
|
+
|
141
|
+
*
|
142
|
+
|
143
|
+
* @author tsukka
|
144
|
+
|
145
|
+
*/
|
146
|
+
|
147
|
+
public class IntPoint {
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
public int x, y;
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
public IntPoint(int x, int y) {
|
156
|
+
|
157
|
+
this.x = x;
|
158
|
+
|
159
|
+
this.y = y;
|
160
|
+
|
161
|
+
}
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
@Override
|
168
|
+
|
169
|
+
public String toString() {
|
170
|
+
|
171
|
+
return '(' + Integer.toString(x) + ',' + Integer.toString(y) + ')';
|
172
|
+
|
173
|
+
}
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
public Point toPoint() {
|
178
|
+
|
179
|
+
return new Point(x, y);
|
180
|
+
|
181
|
+
}
|
182
|
+
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
```
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
```java
|
192
|
+
|
193
|
+
package tsukka.utility.function;
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
/**
|
198
|
+
|
199
|
+
*
|
200
|
+
|
201
|
+
* @author tsukka
|
202
|
+
|
203
|
+
*/
|
204
|
+
|
205
|
+
@FunctionalInterface
|
206
|
+
|
207
|
+
public interface BytePredicate {
|
208
|
+
|
209
|
+
default BytePredicate and(BytePredicate other){
|
210
|
+
|
211
|
+
return b->this.test(b)&&other.test(b);
|
212
|
+
|
213
|
+
}
|
214
|
+
|
215
|
+
default BytePredicate negate(){
|
216
|
+
|
217
|
+
return b->!this.test(b);
|
218
|
+
|
219
|
+
}
|
220
|
+
|
221
|
+
default BytePredicate or(BytePredicate other) {
|
222
|
+
|
223
|
+
return b->this.test(b)||other.test(b);
|
224
|
+
|
225
|
+
}
|
226
|
+
|
227
|
+
boolean test(byte value);
|
228
|
+
|
229
|
+
}
|
230
|
+
|
231
|
+
```
|
232
|
+
|
149
233
|
byteでならとれると思われる
|
150
234
|
|
151
235
|
ちなみに白なら-1(255)黒なら0
|
4
androidでの補足
test
CHANGED
@@ -151,3 +151,7 @@
|
|
151
151
|
ちなみに白なら-1(255)黒なら0
|
152
152
|
|
153
153
|
1ピクセル当たり1インデックス
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
ラムダとか使えないなら適宜書き換えてください
|
3
詳細なソース
test
CHANGED
@@ -1,16 +1,148 @@
|
|
1
1
|
```java
|
2
2
|
|
3
|
-
|
3
|
+
package tsukka.teratail.questions.q103546;
|
4
4
|
|
5
|
-
//二値化
|
6
5
|
|
7
|
-
Imgproc.cvtColor(im, im, Imgproc.COLOR_BGR2GRAY); //グレースケールに変換
|
8
6
|
|
9
|
-
|
7
|
+
import java.util.HashSet;
|
10
8
|
|
11
|
-
|
9
|
+
import java.util.Set;
|
12
10
|
|
11
|
+
import java.util.function.IntPredicate;
|
12
|
+
|
13
|
+
import org.opencv.core.Core;
|
14
|
+
|
15
|
+
import org.opencv.core.CvType;
|
16
|
+
|
17
|
+
import org.opencv.core.Mat;
|
18
|
+
|
19
|
+
import org.opencv.core.Size;
|
20
|
+
|
21
|
+
import org.opencv.imgcodecs.Imgcodecs;
|
22
|
+
|
23
|
+
import org.opencv.imgproc.Imgproc;
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
/**
|
28
|
+
|
29
|
+
*
|
30
|
+
|
31
|
+
* @author tsukka
|
32
|
+
|
33
|
+
*/
|
34
|
+
|
35
|
+
public class Q103546 {
|
36
|
+
|
37
|
+
public static void main (String... args){
|
38
|
+
|
39
|
+
System.out.println(System.getProperty("java.library.path"));
|
40
|
+
|
41
|
+
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
42
|
+
|
43
|
+
//画像読み込み
|
44
|
+
|
45
|
+
Mat im = Imgcodecs.imread("test.png"); // 入力画像の取得
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
//二値化
|
50
|
+
|
51
|
+
Imgproc.cvtColor(im, im, Imgproc.COLOR_BGR2GRAY); //グレースケールに変換
|
52
|
+
|
53
|
+
Imgproc.threshold(im, im, 0, 255, Imgproc.THRESH_OTSU); //閾値を自動で設定
|
54
|
+
|
55
|
+
//二値化ここまで
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
Mat avem2=new Mat(im.size(),CvType.CV_8U);
|
60
|
+
|
61
|
+
//平滑化
|
62
|
+
|
63
|
+
Imgproc.GaussianBlur(im, avem2, new Size(17,13), 0, 0);
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
Imgcodecs.imwrite("out.png", avem2);
|
68
|
+
|
69
|
+
Set<IntPoint> s=getMatchPoints(avem2,c->c>(byte)250);//255*0.98
|
70
|
+
|
71
|
+
s.forEach(System.out::println);
|
72
|
+
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
|
77
|
+
* org.opencv.core.Pointはdoubleしか扱えない罠
|
78
|
+
|
79
|
+
* @param avem2 グレースケールあるいは二値画像
|
80
|
+
|
81
|
+
* @param tester
|
82
|
+
|
83
|
+
* @return
|
84
|
+
|
85
|
+
*/
|
86
|
+
|
87
|
+
public static Set<IntPoint> getMatchPoints(Mat avem2,IntPredicate tester){
|
88
|
+
|
89
|
+
byte [] data =new byte[avem2.width()*avem2.height()];
|
90
|
+
|
91
|
+
HashSet<IntPoint> ret=new HashSet<>();
|
92
|
+
|
13
|
-
|
93
|
+
avem2.get(0,0,data);
|
94
|
+
|
95
|
+
int width=avem2.width();
|
96
|
+
|
97
|
+
int height=avem2.height();
|
98
|
+
|
99
|
+
for(int y=0;y<height;y++) {
|
100
|
+
|
101
|
+
for (int x = 0; x < width; x++) {
|
102
|
+
|
103
|
+
if(tester.test(data[y*width+x])){
|
104
|
+
|
105
|
+
ret.add(new IntPoint(x,y));
|
106
|
+
|
107
|
+
}
|
108
|
+
|
109
|
+
}
|
110
|
+
|
111
|
+
}
|
112
|
+
|
113
|
+
return ret;
|
114
|
+
|
115
|
+
}
|
116
|
+
|
117
|
+
public static class IntPoint{
|
118
|
+
|
119
|
+
public int x,y;
|
120
|
+
|
121
|
+
public IntPoint(int x,int y){
|
122
|
+
|
123
|
+
this.x=x;
|
124
|
+
|
125
|
+
this.y=y;
|
126
|
+
|
127
|
+
}
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
@Override
|
132
|
+
|
133
|
+
public String toString() {
|
134
|
+
|
135
|
+
return '(' + Integer.toString(x) + ',' + Integer.toString(y) + ')';
|
136
|
+
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
}
|
142
|
+
|
143
|
+
}
|
144
|
+
|
145
|
+
|
14
146
|
|
15
147
|
```
|
16
148
|
|
2
補足説明
test
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
```java
|
2
2
|
|
3
3
|
Mat im = Imgcodecs.imread("test.png"); // 入力画像の取得
|
4
|
+
|
5
|
+
//二値化
|
6
|
+
|
7
|
+
Imgproc.cvtColor(im, im, Imgproc.COLOR_BGR2GRAY); //グレースケールに変換
|
8
|
+
|
9
|
+
Imgproc.threshold(im, im, 0, 255, Imgproc.THRESH_OTSU); //閾値を自動で設定
|
4
10
|
|
5
11
|
byte [] data =new byte[im.width()*im.height()];
|
6
12
|
|
@@ -9,3 +15,7 @@
|
|
9
15
|
```
|
10
16
|
|
11
17
|
byteでならとれると思われる
|
18
|
+
|
19
|
+
ちなみに白なら-1(255)黒なら0
|
20
|
+
|
21
|
+
1ピクセル当たり1インデックス
|
1
まぬけなことにgetを入れ忘れたので入れた
test
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
byte [] data =new byte[im.width()*im.height()];
|
6
6
|
|
7
|
+
im.get(0,0,data);
|
8
|
+
|
7
9
|
```
|
8
10
|
|
9
11
|
byteでならとれると思われる
|