@@ -85,7 +85,94 @@ static void findCorrespondenciesOLS(const cv::Mat_<float>& scores, cv::Mat_<int>
85
85
}
86
86
}
87
87
88
- struct OLSTrackerImpl : public OLSTracker
88
+ static float computeEdgeWeight (const cv::Vec2s& curCandiPoint, const cv::Vec2s& preCandiPoint)
89
+ {
90
+ float spatial_dist = (float )cv::norm (curCandiPoint - preCandiPoint, cv::NORM_L2SQR);
91
+ return std::exp (-spatial_dist/1000 .0f );
92
+ }
93
+
94
+ static void findCorrespondenciesGOS (Mat& bundleGrad, Mat_<float >& fgScores, Mat_<float >& bgScores,
95
+ const Mat_<Vec2s>& imgLocations, Mat_<int >& cols)
96
+ {
97
+ // combine scores
98
+ Mat_<float > scores;
99
+ exp ((fgScores + bgScores)/10 .0f , scores);
100
+
101
+ Mat_<int > fromLocations (scores.size ());
102
+ fromLocations = 0 ;
103
+
104
+ // source node
105
+ bool hasCandidate = false ;
106
+ for (int j=0 ; j<bundleGrad.cols ; j++)
107
+ {
108
+ if (bundleGrad.at <uchar>(0 , j))
109
+ {
110
+ hasCandidate = true ;
111
+ fromLocations (0 , j) = j;
112
+ }
113
+ }
114
+ // fall back to using center as candidate
115
+ if (!hasCandidate)
116
+ {
117
+ fromLocations (0 , bundleGrad.cols /2 ) = bundleGrad.cols /2 ;
118
+ }
119
+
120
+ int index_max_location = 0 ; // index in preceding line for backtracking
121
+
122
+ // the other layers
123
+ for (int i=1 ; i<bundleGrad.rows ; i++)
124
+ {
125
+ hasCandidate = false ;
126
+ for (int j=0 ; j<bundleGrad.cols ; j++)
127
+ {
128
+ if (bundleGrad.at <uchar>(i, j))
129
+ hasCandidate = true ;
130
+ }
131
+ if (!hasCandidate)
132
+ {
133
+ bundleGrad.at <uchar>(i, bundleGrad.cols /2 ) = 255 ;
134
+ }
135
+
136
+ for (int j=0 ; j<bundleGrad.cols ; j++)
137
+ {
138
+ // search for max combined score
139
+ float max_energy = -INFINITY;
140
+ int location = bundleGrad.cols /2 ;
141
+
142
+ if (bundleGrad.at <uchar>(i, j))
143
+ {
144
+ for (int k=0 ; k<bundleGrad.cols ; k++)
145
+ {
146
+ if (bundleGrad.at <uchar>(i - 1 , k))
147
+ {
148
+ float edge_weight = computeEdgeWeight (imgLocations (i, j), imgLocations (i - 1 , k));
149
+ float energy = scores (i, j) + scores (i-1 , k) + edge_weight;
150
+ if (max_energy < energy)
151
+ {
152
+ max_energy = energy;
153
+ location = k;
154
+ }
155
+ }
156
+ }
157
+
158
+ scores (i, j) = max_energy; // update the score
159
+ fromLocations (i, j) = location;
160
+ index_max_location = j;
161
+ }
162
+ }
163
+ }
164
+
165
+ cols.resize (scores.rows );
166
+
167
+ // backtrack along best path
168
+ for (int i = bundleGrad.rows - 1 ; i >= 0 ; i--)
169
+ {
170
+ cols (i) = index_max_location;
171
+ index_max_location = fromLocations (i, index_max_location);
172
+ }
173
+ }
174
+
175
+ struct HistTrackerImpl : public OLSTracker
89
176
{
90
177
Mat vtx;
91
178
Mat tris;
@@ -95,15 +182,18 @@ struct OLSTrackerImpl : public OLSTracker
95
182
double tau;
96
183
uchar sobelThresh;
97
184
98
- OLSTrackerImpl (InputArray _pts3d, InputArray _tris, int histBins, uchar _sobelThesh)
185
+ bool useGOS;
186
+
187
+ HistTrackerImpl (InputArray _pts3d, InputArray _tris, int histBins, uchar _sobelThesh, bool _useGOS)
99
188
{
100
189
CV_Assert (_tris.getMat ().checkVector (3 , CV_32S) > 0 );
101
190
CV_Assert (_pts3d.getMat ().checkVector (3 , CV_32F) > 0 );
102
191
vtx = _pts3d.getMat ();
103
192
tris = _tris.getMat ();
104
193
105
- tau = 1.0 ; // currently does not work as intended. effectively disable
194
+ tau = 0.7 ; // this is 1 - tau compared to OLS paper
106
195
sobelThresh = _sobelThesh;
196
+ useGOS = _useGOS;
107
197
108
198
bgHist.create (histBins, histBins);
109
199
}
@@ -129,7 +219,7 @@ struct OLSTrackerImpl : public OLSTracker
129
219
130
220
double s = bhattacharyyaCoeff (fgHist, hist);
131
221
// handle object clutter as in eq. (5)
132
- if (( 1.0 - s) > tau)
222
+ if (s > tau)
133
223
s = 1.0 - bhattacharyyaCoeff (bgHist, hist);
134
224
scores (i, j) = float (s);
135
225
start = j;
@@ -138,6 +228,36 @@ struct OLSTrackerImpl : public OLSTracker
138
228
}
139
229
}
140
230
231
+ void computeBackgroundScores (const Mat& bundleHSV, const Mat& bundleGrad, Mat_<float >& scores)
232
+ {
233
+ scores.resize (bundleHSV.rows );
234
+ scores = 0 ;
235
+
236
+ Mat_<float > hist (fgHist.size ());
237
+
238
+ for (int i = 0 ; i < bundleHSV.rows ; i++)
239
+ {
240
+ int end = bundleHSV.cols - 1 ;
241
+ for (int j = bundleHSV.cols - 1 ; j >= 0 ; j--)
242
+ {
243
+ if (bundleGrad.at <uchar>(i, j))
244
+ {
245
+ // compute the histogram between last candidate point to current candidate point
246
+ hist = 0 ;
247
+ calcHueSatHist (bundleHSV ({i, i + 1 }, {j, end}), hist);
248
+ hist /= std::max (sum (hist), 1 .0f );
249
+
250
+ double s = 1 - bhattacharyyaCoeff (fgHist, hist);
251
+ if (s <= tau)
252
+ s = bhattacharyyaCoeff (bgHist, hist);
253
+
254
+ scores (i, j) = float (s);
255
+ end = j;
256
+ }
257
+ }
258
+ }
259
+ }
260
+
141
261
void updateFgBgHist (const Mat_<Vec3b>& hsv, const Mat_<int >& cols)
142
262
{
143
263
fgHist = 0 ;
@@ -189,7 +309,17 @@ struct OLSTrackerImpl : public OLSTracker
189
309
190
310
Mat_<float > scores (lineBundle.size ());
191
311
computeAppearanceScores (bundleHSV, bundleGrad, scores);
192
- findCorrespondenciesOLS (scores, cols);
312
+
313
+ if (useGOS)
314
+ {
315
+ Mat_<float > bgScores (scores.size ());
316
+ computeBackgroundScores (bundleHSV, bundleGrad, bgScores);
317
+ findCorrespondenciesGOS (bundleGrad, scores, bgScores, imgLoc, cols);
318
+ }
319
+ else
320
+ {
321
+ findCorrespondenciesOLS (scores, cols);
322
+ }
193
323
194
324
convertCorrespondencies (cols, imgLoc, pts2d, pts3d, cols > -1 );
195
325
@@ -224,7 +354,12 @@ struct OLSTrackerImpl : public OLSTracker
224
354
225
355
Ptr<OLSTracker> OLSTracker::create (InputArray pts3d, InputArray tris, int histBins, uchar sobelThesh)
226
356
{
227
- return makePtr<OLSTrackerImpl>(pts3d, tris, histBins, sobelThesh);
357
+ return makePtr<HistTrackerImpl>(pts3d, tris, histBins, sobelThesh, false );
358
+ }
359
+
360
+ Ptr<OLSTracker> GOSTracker::create (InputArray pts3d, InputArray tris, int histBins, uchar sobelThesh)
361
+ {
362
+ return makePtr<HistTrackerImpl>(pts3d, tris, histBins, sobelThesh, true );
228
363
}
229
364
230
365
} // namespace rapid
0 commit comments