Skip to content

Commit dc991ab

Browse files
committed
Figs bugs, add window option to emvisi2_video
- fix a memory issue (allocation too small) - fix some numerical instability
1 parent 52f2287 commit dc991ab

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

emvisi2.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ void EMVisi2::run(int nbIter, float smooth_amount, float smooth_threshold)
105105
reset_gaussians();
106106
}
107107
for (int i=0;i<nbIter;i++) {
108-
iterate();
108+
if (!iterate()) {
109+
break;
110+
}
109111
}
110112
if (smooth_amount>0)
111113
smooth(smooth_amount, smooth_threshold);
@@ -127,7 +129,7 @@ void EMVisi2::reset_gaussians()
127129
weights[i] = 1.0f/(NB_GAUSSIANS+1);
128130
}
129131

130-
void EMVisi2::iterate()
132+
bool EMVisi2::iterate()
131133
{
132134
char str[256];
133135
uniform_resp=0;
@@ -171,12 +173,20 @@ void EMVisi2::iterate()
171173
for (int i=0; i<NB_VISI_GAUSSIANS; i++) {
172174
visi_g[i].compute_sigma();
173175
totN += visi_g[i].n;
176+
if (visi_g[i].n < 1e-2f) {
177+
recycle = false;
178+
return false;
179+
}
174180
}
175181

176182
for (int i=0; i<NB_OCCL_GAUSSIANS; i++) {
177183
occl_g[i].compute_sigma();
178184
totN += occl_g[i].n;
179-
}
185+
if (occl_g[i].n < 1e-2f) {
186+
recycle = false;
187+
return false;
188+
}
189+
}
180190

181191
totN += uniform_resp;
182192
weights[NB_GAUSSIANS] = uniform_resp/totN;
@@ -199,6 +209,7 @@ void EMVisi2::iterate()
199209
sprintf(str, "proba%02d.png", iteration );
200210
scale_save(str, proba, -1, -1);
201211
}
212+
return true;
202213
}
203214

204215
float EMVisi2::process_pixel(const float *rgb, const float *frgb, const float dl, const float nccv, const float ncch, float *proba, float *visi_proba)
@@ -511,7 +522,7 @@ void EMVisi2::smooth(float amount, float threshold) {
511522
}
512523

513524
// allocate the graph. Note: worst case memory scenario.
514-
int n_nodes= gc_mask.cols * gc_mask.rows;
525+
int n_nodes= (gc_mask.cols + 2) * (gc_mask.rows + 2);
515526
int n_edges = 2*((wa.cols)*(wa.rows-1) + (wa.cols-1)*wa.rows);
516527
FGraph g(n_nodes, n_edges);
517528
int *nodesid = new int[n_nodes];
@@ -546,6 +557,8 @@ void EMVisi2::smooth(float amount, float threshold) {
546557
if (m[x] == rval) {
547558
// add a new node
548559
int next_node = g.addVtx();
560+
assert(row_id >= nodesid);
561+
assert(row_id < nodesid + n_nodes);
549562
*row_id = next_node;
550563

551564
// terminal weights
@@ -601,7 +614,7 @@ void EMVisi2::smooth(float amount, float threshold) {
601614

602615
for (int x=rect.x; x<rect.x+rect.width; x++) {
603616
if (*row_id >= 0) {
604-
p[x] = !g.inSourceSegment(*row_id);
617+
p[x] = (g.inSourceSegment(*row_id) ? 0 : 1);
605618
}
606619
row_id++;
607620
}

emvisi2.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class EMVisi2 {
9090
bool init();
9191
int setModel(const cv::Mat im1, const cv::Mat mask = cv::Mat());
9292
int setTarget(cv::Mat target);
93-
void iterate();
93+
bool iterate();
9494
void smooth(float amount, float threshold);
9595
void run(int nbIter=3, float smooth_amount=2.5, float smooth_threshold=.0001);
9696
float process_pixel(const float *rgb, const float *frgb, const float dl, const float nccv, const float ncch, float *proba, float *visi_proba);

emvisi2_video.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ int main(int argc, char *argv[])
6161
cv::Mat background;
6262
list<string> images;
6363
path destinationFolder("out");
64+
bool window = false;
6465

6566
// parse command line
6667
for (int narg=1; narg<argc; ++narg) {
@@ -85,6 +86,8 @@ int main(int argc, char *argv[])
8586

8687
if (strcmp(argv[narg],"-v")==0) {
8788
emv.save_images=true;
89+
} else if (strcmp(argv[narg],"-w")==0) {
90+
window = true;
8891
} else if (strcmp(argv[narg],"-s")==0) {
8992
smooth = 0.001f;
9093
} else if (argv[narg][0] == '-') {
@@ -111,6 +114,8 @@ int main(int argc, char *argv[])
111114

112115
cout << "done in " << timer.duration() << " ms.\n";
113116

117+
int playing = 0;
118+
114119
for (list<string>::const_iterator it = images.begin();
115120
it != images.end(); ++it) {
116121
Mat frame = loadImage(*it, -1);
@@ -128,6 +133,21 @@ int main(int argc, char *argv[])
128133
cout << "computed in " << timer.duration() << " ms.\n";
129134

130135
save_proba(destinationFilename(*it, destinationFolder).c_str(),emv.proba);
136+
137+
if (window) {
138+
std::vector<cv::Mat> channels;
139+
cv::split(frame, channels);
140+
emv.proba.convertTo(channels[1], CV_8UC1, 255, 0);
141+
cv::Mat result;
142+
cv::merge(channels, result);
143+
144+
imshow("Segmentation", result);
145+
int k = cv::waitKey(playing);
146+
switch (k) {
147+
case ' ': playing = (playing + 1) & 1; break;
148+
case 'p': --it; --it; break;
149+
}
150+
}
131151
}
132152
return 0;
133153
}

imstat.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,19 @@ class MultiGaussian3 : public Accumulator<T> {
232232
+t14*sigma[2][2]
233233
+t15+t15;
234234

235+
float epsilon = 1e-30;
236+
237+
if (isnan(vsv)) {
238+
return epsilon;
239+
}
240+
235241
assert(!isnan(vsv));
236242
assert(!isnan(one_over_sq_det));
237243
if (vsv<0) vsv=0;
238244

239245
// this constant is 1/(2Pi)^(3/2)
240246
float p = .0634936359342409f*one_over_sq_det*exp_table(-.5f*vsv);
241247

242-
float epsilon = 1e-30;
243248
if (p<epsilon) p=epsilon;
244249

245250
assert(!isnan(p));

0 commit comments

Comments
 (0)