From a87607e3ef6d30a2ccd8bd3b516fde4647dce16d Mon Sep 17 00:00:00 2001 From: Firat Kalaycilar Date: Wed, 12 Mar 2014 16:14:59 +0200 Subject: [PATCH 1/2] Fixed an issue with weight assignment causing the resulting GMM weights to be unsorted in BackgroundSubtractorMOG2 --- modules/video/src/bgfg_gaussmix2.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/video/src/bgfg_gaussmix2.cpp b/modules/video/src/bgfg_gaussmix2.cpp index 6bbb96048..b14bc8e1e 100644 --- a/modules/video/src/bgfg_gaussmix2.cpp +++ b/modules/video/src/bgfg_gaussmix2.cpp @@ -319,7 +319,7 @@ struct MOG2Invoker : ParallelLoopBody for( int mode = 0; mode < nmodes; mode++, mean_m += nchannels ) { float weight = alpha1*gmm[mode].weight + prune;//need only weight if fit is found - + int swap_count = 0; //// //fit not found yet if( !fitsPDF ) @@ -384,6 +384,7 @@ struct MOG2Invoker : ParallelLoopBody if( weight < gmm[i-1].weight ) break; + swap_count++; //swap one up std::swap(gmm[i], gmm[i-1]); for( int c = 0; c < nchannels; c++ ) @@ -401,7 +402,7 @@ struct MOG2Invoker : ParallelLoopBody nmodes--; } - gmm[mode].weight = weight;//update weight by the calculated value + gmm[mode-swap_count].weight = weight;//update weight by the calculated value totalWeight += weight; } //go through all modes From 0a16d93e1d2b8c23df77c769589cfc7982c68af1 Mon Sep 17 00:00:00 2001 From: Firat Kalaycilar Date: Tue, 18 Mar 2014 17:26:24 +0200 Subject: [PATCH 2/2] Fixed an issue with weight assignment causing the resulting GMM weights to be unsorted in the CUDA and OCL versions of BackgroundSubtractorMOG2 --- modules/gpu/src/cuda/bgfg_mog.cu | 5 +++-- modules/ocl/src/opencl/bgfg_mog.cl | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/gpu/src/cuda/bgfg_mog.cu b/modules/gpu/src/cuda/bgfg_mog.cu index 89ad5ff0b..055c9e041 100644 --- a/modules/gpu/src/cuda/bgfg_mog.cu +++ b/modules/gpu/src/cuda/bgfg_mog.cu @@ -489,7 +489,7 @@ namespace cv { namespace gpu { namespace device { //need only weight if fit is found float weight = alpha1 * gmm_weight(mode * frame.rows + y, x) + prune; - + int swap_count = 0; //fit not found yet if (!fitsPDF) { @@ -540,6 +540,7 @@ namespace cv { namespace gpu { namespace device if (weight < gmm_weight((i - 1) * frame.rows + y, x)) break; + swap_count++; //swap one up swap(gmm_weight, x, y, i - 1, frame.rows); swap(gmm_variance, x, y, i - 1, frame.rows); @@ -557,7 +558,7 @@ namespace cv { namespace gpu { namespace device nmodes--; } - gmm_weight(mode * frame.rows + y, x) = weight; //update weight by the calculated value + gmm_weight((mode - swap_count) * frame.rows + y, x) = weight; //update weight by the calculated value totalWeight += weight; } diff --git a/modules/ocl/src/opencl/bgfg_mog.cl b/modules/ocl/src/opencl/bgfg_mog.cl index 6a95316f0..a7479b929 100644 --- a/modules/ocl/src/opencl/bgfg_mog.cl +++ b/modules/ocl/src/opencl/bgfg_mog.cl @@ -376,7 +376,7 @@ __kernel void mog2_kernel(__global T_FRAME * frame, __global int* fgmask, __glob for (int mode = 0; mode < nmodes; ++mode) { float _weight = alpha1 * weight[(mode * frame_row + y) * weight_step + x] + prune; - + int swap_count = 0; if (!fitsPDF) { float var = variance[(mode * frame_row + y) * var_step + x]; @@ -404,6 +404,7 @@ __kernel void mog2_kernel(__global T_FRAME * frame, __global int* fgmask, __glob { if (_weight < weight[((i - 1) * frame_row + y) * weight_step + x]) break; + swap_count++; swap(weight, x, y, i - 1, frame_row, weight_step); swap(variance, x, y, i - 1, frame_row, var_step); #if defined (CN1) @@ -421,7 +422,7 @@ __kernel void mog2_kernel(__global T_FRAME * frame, __global int* fgmask, __glob nmodes--; } - weight[(mode * frame_row + y) * weight_step + x] = _weight; //update weight by the calculated value + weight[((mode - swap_count) * frame_row + y) * weight_step + x] = _weight; //update weight by the calculated value totalWeight += _weight; }