15
15
import org .apache .commons .math3 .stat .regression .SimpleRegression ;
16
16
import org .eclipse .collections .api .IntIterable ;
17
17
import org .eclipse .collections .api .list .primitive .IntList ;
18
+ import org .eclipse .collections .api .tuple .primitive .IntIntPair ;
18
19
import org .eclipse .collections .impl .list .mutable .primitive .IntArrayList ;
19
20
import ptrman .Datastructures .Vector2d ;
20
21
import ptrman .bpsolver .HardParameters ;
21
22
import ptrman .bpsolver .Parameters ;
22
23
import ptrman .levels .retina .helper .ProcessConnector ;
24
+ import ptrman .math .ArrayRealVectorHelper ;
23
25
import ptrman .misc .Assert ;
24
26
25
27
import java .util .*;
@@ -109,51 +111,101 @@ public void removeCandidatesBelowActivation(double threshold) {
109
111
}
110
112
}
111
113
112
- // tries to sample a new line candidate
113
- public void sampleNew () {
114
- final double maxLength = Math .sqrt (squaredDistance (new double []{imageSize .x , imageSize .y })); // max length of line
115
-
116
- List <LineDetectorWithMultiplePoints > multiplePointsLineDetector = new ArrayList <>();
117
114
118
- final List <ProcessA .Sample > workingSamples = inputSampleConnector .getWorkspace ();
119
-
120
- if (workingSamples .isEmpty ()) {
121
- return ;
115
+ /**
116
+ * selects random samples
117
+ * @param source
118
+ * @return
119
+ */
120
+ public List <ProcessA .Sample > selectRandomSamples (List <ProcessA .Sample > source ) {
121
+ if (source .size () < 3 ) {
122
+ return new ArrayList <>();
122
123
}
123
124
124
125
// pick out random points
125
126
int sampleIndex = 0 ; // NOTE< index in endosceletonPoint / workingSamples >
126
127
IntArrayList allCandidateSampleIndices = new IntArrayList ();
128
+ for (final ProcessA .Sample iterationSample : source ) {
129
+ allCandidateSampleIndices .add (sampleIndex );
130
+ sampleIndex ++;
131
+ }
132
+
133
+ IntList chosenCandidateSampleIndices = getRandomElements (allCandidateSampleIndices , 3 , rng );
134
+ return getSamplesByIndices (source , chosenCandidateSampleIndices );
135
+ }
136
+
137
+ /**
138
+ * tries to sample a new line candidate by picking random points
139
+ */
140
+ public void sampleNewByRandom () {
141
+ final double maxLength = Math .sqrt (squaredDistance (new double []{imageSize .x , imageSize .y })); // max length of line
142
+
143
+ List <LineDetectorWithMultiplePoints > multiplePointsLineDetector = new ArrayList <>();
144
+
145
+ final List <ProcessA .Sample > workingSamples = inputSampleConnector .getWorkspace ();
146
+
147
+ // filter valid points
148
+ List <ProcessA .Sample > filteredSamples = new ArrayList <>();
127
149
for (final ProcessA .Sample iterationSample : workingSamples ) {
128
150
boolean onlyAddEndoskeletonEnable = !(onlyEndoskeleton && iterationSample .type != ProcessA .Sample .EnumType .ENDOSCELETON );
129
151
boolean isReferenced = iterationSample .refCount != 0 ;
130
152
if (!isReferenced && onlyAddEndoskeletonEnable ) {
131
- allCandidateSampleIndices .add (sampleIndex );
153
+ filteredSamples .add (iterationSample );
132
154
}
133
- sampleIndex ++;
134
155
}
135
156
157
+ List <ProcessA .Sample > selectedSamples = selectRandomSamples (filteredSamples );
158
+ tryCreateMultiLineDetector (maxLength , selectedSamples );
159
+ }
136
160
137
- IntList chosenCandidateSampleIndices = getRandomElements (allCandidateSampleIndices , 3 , rng );
138
- List <ProcessA .Sample > selectedSamples = getSamplesByIndices (workingSamples , chosenCandidateSampleIndices );
161
+ public double processDSampleByProximityProximity = 20.0 ; // maximal proximity of points to get considered for sampling by proximity
162
+
163
+ /**
164
+ * tries to sample a new detector by proximity of points
165
+ */
166
+ public void sampleNewByProximity () {
167
+ final double maxLength = Math .sqrt (squaredDistance (new double []{imageSize .x , imageSize .y })); // max length of line
168
+
169
+ final List <ProcessA .Sample > workingSamples = inputSampleConnector .getWorkspace ();
139
170
140
- tryCreateMultiLineDetector (maxLength , chosenCandidateSampleIndices , selectedSamples );
171
+ if (workingSamples .size () < 2 ) {
172
+ return ;
173
+ }
174
+
175
+ int centerPointIdx = rng .nextInt (workingSamples .size ());
176
+ IntIntPair centerPointPos = workingSamples .get (centerPointIdx ).position ;
177
+
178
+ // find all points in proximity
179
+ List <ProcessA .Sample > proximitySamples = new ArrayList <>();
180
+ for (ProcessA .Sample iSample : workingSamples ) {
181
+ double dist = ArrayRealVectorHelper .distance (centerPointPos , iSample .position );
182
+ if (dist > processDSampleByProximityProximity ) {
183
+ continue ;
184
+ }
185
+
186
+ boolean onlyAddEndoskeletonEnable = !(onlyEndoskeleton && iSample .type != ProcessA .Sample .EnumType .ENDOSCELETON );
187
+ boolean isReferenced = iSample .refCount != 0 ;
188
+ if (!isReferenced && onlyAddEndoskeletonEnable ) {
189
+ proximitySamples .add (iSample );
190
+ }
191
+ }
141
192
193
+ // try to create line detector by selecting random points from candidates
194
+ List <ProcessA .Sample > selectedSamples = selectRandomSamples (proximitySamples );
195
+ tryCreateMultiLineDetector (maxLength , selectedSamples );
142
196
}
143
197
144
198
public double processDNumberOfPointsToActivationScale = 0.15 ; // how much does a point improve the scaling
145
199
146
- private void tryCreateMultiLineDetector (
147
- double maxLength ,
148
- IntList chosenCandidateSampleIndices , List <ProcessA .Sample > selectedSamples ) {
200
+ private void tryCreateMultiLineDetector (double maxLength , List <ProcessA .Sample > selectedSamples ) {
149
201
// commented check because we don't assume object id's anymore (because it was from Phaeaco for solving BP's)
150
202
//final boolean doAllSamplesHaveId = doAllSamplesHaveObjectId(selectedSamples);
151
203
//if (!doAllSamplesHaveId) {
152
204
// return;
153
205
//}
154
206
155
- if (selectedSamples .size () == 0 ) {
156
- return ; // special case
207
+ if (selectedSamples .size () < 2 ) {
208
+ return ; // line is not defined
157
209
}
158
210
159
211
// check if object ids are the same
@@ -180,14 +232,13 @@ private void tryCreateMultiLineDetector(
180
232
}
181
233
// else we are here
182
234
183
- if (chosenCandidateSampleIndices .size () <= 2 ) { // the regression mse is not defined if it are only two points
235
+ if (selectedSamples .size () <= 2 ) { // the regression mse is not defined if it are only two points
184
236
return ; // only create detector if we have at least three samples
185
237
}
186
238
187
239
188
240
// create new line detector
189
241
LineDetectorWithMultiplePoints createdLineDetector = new LineDetectorWithMultiplePoints (lineDetectorInitialXStep );
190
- createdLineDetector .integratedSampleIndices = chosenCandidateSampleIndices ;
191
242
createdLineDetector .samples = selectedSamples ;
192
243
193
244
Assert .Assert (areObjectIdsTheSameOfSamples (selectedSamples ), "" );
@@ -198,7 +249,7 @@ private void tryCreateMultiLineDetector(
198
249
199
250
boolean addCreatedLineDetector = false ;
200
251
201
- if (createdLineDetector .integratedSampleIndices .size () == 2 ) {
252
+ if (createdLineDetector .samples .size () == 2 ) {
202
253
createdLineDetector .mse = 0.0f ;
203
254
204
255
createdLineDetector .n = regressionResult .n ;
@@ -279,7 +330,8 @@ private static List<RetinaPrimitive> splitDetectorsIntoLines(Iterable<LineDetect
279
330
* processing step
280
331
*/
281
332
public void step () {
282
- sampleNew ();
333
+ sampleNewByRandom ();
334
+ sampleNewByProximity ();
283
335
tryWiden ();
284
336
detectorsHarden ();
285
337
detectorsFadeActivation ();
0 commit comments