sample bgfg_segm.cpp don't display background in 2.1.0 version (Bug #317)
Description
Sample $OPENCV/samples/c/bffg_segm.cpp returns a black image as background in version 2.1.0. Version 2.0.0 works fine.
Seems like cvUpdateBGStatModel() funtion don't update the background image in the CvBGStatModel object.
Environment:
opencv = 2.1.0
compiler= g++ (GCC) 4.4.3 20100127 (Red Hat 4.4.3-4)
system = Linux 2.6.32.11-99.fc12.x86_64 #1 SMP Mon Apr 5 19:59:38 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
Related issues
duplicated by Bug #622: Mixture of gaussians doesn't return any background | Cancelled |
Associated revisions
Added displaying of the mean background image in the bgfg_segm sample (ticket #317).
Merge pull request #317 from vpisarev:c2cpp_refactor_imgproc
History
Updated by Bruno Nascimento over 14 years ago
i had the same problem
Updated by Gerard Torrent over 14 years ago
The following function fills model->background image when model is MOG (cvCreateGaussianBGModel). I hope this helps those who encounter this problem in the meanwhile.
1typedef struct [[MyCvGaussBGValues]]
2{
3 float match_sum;
4 float weight;
5 float meanr3;
6 float variancer3;
7}
8[[MyCvGaussBGValues]];
9
10static void updateBackground(CvGaussBGModel* bg_model)
11{
12 int K = bg_model->params.n_gauss;
13 int nchannels = bg_model->background->nChannels;
14 int height = bg_model->background->height;
15 int width = bg_model->background->width;
16 MyCvGaussBGValues *g_point = (MyCvGaussBGValues *) ((CvMat*)(bg_model->g_point))->data.ptr;
17 MyCvGaussBGValues *mptr = g_point;
18
19 for(int y=0; y<height; y++)
20 {
21 for (int x=0; x<width; x++, mptr+=K)
22 {
23 int pos = bg_model->background->widthStep*y + x*nchannels;
24 float meanr3 = {0.0, 0.0, 0.0};
25
26 for(int k=0; k<K; k++)
27 {
28 for(int m=0; m<nchannels; m++)
29 {
30 mean[m] += mptr[k].weight * mptr[k].mean[m];
31 }
32 }
33
34 for(int m=0; m<nchannels; m++)
35 {
36 bg_model->background->imageData[pos+m] = (uchar) (mean[m]+0.5);
37 }
38 }
39 }
40}
41
Call just after cvUpdateBGStatModel(), as this:
1cvUpdateBGStatModel( tmp_frame, bg_model, update_bg_model ? -1 : 0 );
2updateBackground((CvGaussBGModel*)bg_model);
Note: works only for 3-channels images.
Updated by Gerard Torrent about 14 years ago
Improved previous version. Anyone here?
1typedef struct [[MixData]]1
2{
3 float match_sum;
4 float weight;
5 float mean;
6 float variance;
7}
8[[MixData]]1;
9
10typedef struct [[MixData]]3
11{
12 float match_sum;
13 float weight;
14 float meanr3;
15 float variancer3;
16}
17[[MixData]]3;
18
19void [[BackgroundThread]]::update8uC1(CvGaussBGModel* bg_model)
20{
21 int K = bg_model->params.n_gauss;
22 float T = bg_model->params.bg_threshold;
23 int height = bg_model->background->height;
24 int width = bg_model->background->width;
25 MixData1 *g_point = (MixData1 *) ((CvMat*)(bg_model->g_point))->data.ptr;
26 MixData1 *mptr = g_point;
27
28 for(int y=0; y<height; y++)
29 {
30 for (int x=0; x<width; x++, mptr+=K)
31 {
32 int pos = bg_model->background->widthStep*y + x;
33 float mean = 0.0;
34 float wsum = 0.0;
35 int kForeground = K;
36
37 for(int k=0; k<K; k++)
38 {
39 wsum += mptr[k].weight;
40 if (wsum > T)
41 {
42 kForeground = k+1;
43 break;
44 }
45 }
46
47 for(int k=0; k<kForeground; k++)
48 {
49 mean += mptr[k].weight * mptr[k].mean;
50 }
51
52 bg_model->background->imageData[pos] = (uchar) (mean/wsum);
53 }
54 }
55}
56
57void [[BackgroundThread]]::update8uC3(CvGaussBGModel* bg_model)
58{
59 int K = bg_model->params.n_gauss;
60 float T = bg_model->params.bg_threshold;
61 int nchannels = bg_model->background->nChannels;
62 int height = bg_model->background->height;
63 int width = bg_model->background->width;
64 MixData3 *g_point = (MixData3 *) ((CvMat*)(bg_model->g_point))->data.ptr;
65 MixData3 *mptr = g_point;
66
67 for(int y=0; y<height; y++)
68 {
69 for (int x=0; x<width; x++, mptr+=K)
70 {
71 int pos = bg_model->background->widthStep*y + x*nchannels;
72 float meanr3 = {0.0, 0.0, 0.0};
73 float wsum = 0.0;
74 int kForeground = K;
75
76 for(int k=0; k<K; k++)
77 {
78 wsum += mptr[k].weight;
79 if (wsum > T)
80 {
81 kForeground = k+1;
82 break;
83 }
84 }
85
86 for(int k=0; k<kForeground; k++)
87 {
88 for(int m=0; m<nchannels; m++)
89 {
90 mean[m] += mptr[k].weight * mptr[k].mean[m];
91 }
92 }
93
94 for(int m=0; m<nchannels; m++)
95 {
96 bg_model->background->imageData[pos+m] = (uchar) (mean[m]/wsum); //+0.5
97 }
98 }
99 }
100}
101
Call just after cvUpdateBGStatModel(), as this:
1cvUpdateBGStatModel(image, model, -1);
2update8uC3((CvGaussBGModel*)model);
Updated by Ilya Lysenkov almost 14 years ago
- Status deleted (
Open)
Updated by Ilya Lysenkov almost 14 years ago
Thank you! I've modified the sample in -r5344 and -r5345 to display a mean background image as gtorrent has proposed.
- Status set to Done
- (deleted custom field) set to fixed
Updated by anay sonawane about 12 years ago
Where to use this code i.e in which lib?