From 4dbc7600e787fee2d02ccaf8b5698396c7ff14ad Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 13 Aug 2012 10:28:42 +0400 Subject: [PATCH] added support of all types to BackgroundSubtractorGMG --- .../include/opencv2/video/background_segm.hpp | 2 +- modules/video/src/bgfg_gmg.cpp | 73 +++++++++------------- 2 files changed, 32 insertions(+), 43 deletions(-) diff --git a/modules/video/include/opencv2/video/background_segm.hpp b/modules/video/include/opencv2/video/background_segm.hpp index 9c37ffa..2ec21ee 100644 --- a/modules/video/include/opencv2/video/background_segm.hpp +++ b/modules/video/include/opencv2/video/background_segm.hpp @@ -251,7 +251,7 @@ private: int frameNum_; cv::Mat_ nfeatures_; - cv::Mat_ colors_; + cv::Mat_ colors_; cv::Mat_ weights_; cv::Mat buf_; diff --git a/modules/video/src/bgfg_gmg.cpp b/modules/video/src/bgfg_gmg.cpp index acec3ed..881f552 100644 --- a/modules/video/src/bgfg_gmg.cpp +++ b/modules/video/src/bgfg_gmg.cpp @@ -91,7 +91,7 @@ void cv::BackgroundSubtractorGMG::initialize(cv::Size frameSize, double min, dou namespace { - float findFeature(int color, const int* colors, const float* weights, int nfeatures) + float findFeature(uint color, const uint* colors, const float* weights, int nfeatures) { for (int i = 0; i < nfeatures; ++i) { @@ -116,7 +116,7 @@ namespace } } - bool insertFeature(int color, float weight, int* colors, float* weights, int& nfeatures, int maxFeatures) + bool insertFeature(uint color, float weight, uint* colors, float* weights, int& nfeatures, int maxFeatures) { int idx = -1; for (int i = 0; i < nfeatures; ++i) @@ -134,7 +134,7 @@ namespace { // move feature to beginning of list - ::memmove(colors + 1, colors, idx * sizeof(int)); + ::memmove(colors + 1, colors, idx * sizeof(uint)); ::memmove(weights + 1, weights, idx * sizeof(float)); colors[0] = color; @@ -144,7 +144,7 @@ namespace { // discard oldest feature - ::memmove(colors + 1, colors, (nfeatures - 1) * sizeof(int)); + ::memmove(colors + 1, colors, (nfeatures - 1) * sizeof(uint)); ::memmove(weights + 1, weights, (nfeatures - 1) * sizeof(float)); colors[0] = color; @@ -166,45 +166,31 @@ namespace namespace { - template struct Quantization_ - { - template - static inline int apply(T val, double minVal, double maxVal, int quantizationLevels) - { - int res = 0; - res |= static_cast((val[0] - minVal) * quantizationLevels / (maxVal - minVal)); - res |= static_cast((val[1] - minVal) * quantizationLevels / (maxVal - minVal)) << 8; - res |= static_cast((val[2] - minVal) * quantizationLevels / (maxVal - minVal)) << 16; - return res; - } - }; - template <> struct Quantization_<1> - { - template - static inline int apply(T val, double minVal, double maxVal, int quantizationLevels) - { - return static_cast((val - minVal) * quantizationLevels / (maxVal - minVal)); - } - }; template struct Quantization { - static int apply(const void* src_, int x, double minVal, double maxVal, int quantizationLevels) + static uint apply(const void* src_, int x, int cn, double minVal, double maxVal, int quantizationLevels) { const T* src = static_cast(src_); - return Quantization_::channels>::apply(src[x], minVal, maxVal, quantizationLevels); + src += x * cn; + + uint res = 0; + for (int i = 0, shift = 0; i < cn; ++i, ++src, shift += 8) + res |= static_cast((*src - minVal) * quantizationLevels / (maxVal - minVal)) << shift; + + return res; } }; class GMG_LoopBody : public cv::ParallelLoopBody { public: - GMG_LoopBody(const cv::Mat& frame, const cv::Mat& fgmask, const cv::Mat_& nfeatures, const cv::Mat_& colors, const cv::Mat_& weights, + GMG_LoopBody(const cv::Mat& frame, const cv::Mat& fgmask, const cv::Mat_& nfeatures, const cv::Mat_& colors, const cv::Mat_& weights, int maxFeatures, double learningRate, int numInitializationFrames, int quantizationLevels, double backgroundPrior, double decisionThreshold, double maxVal, double minVal, int frameNum, bool updateBackgroundModel) : frame_(frame), fgmask_(fgmask), nfeatures_(nfeatures), colors_(colors), weights_(weights), - maxFeatures_(maxFeatures), learningRate_(learningRate), numInitializationFrames_(numInitializationFrames), - quantizationLevels_(quantizationLevels), backgroundPrior_(backgroundPrior), decisionThreshold_(decisionThreshold), - maxVal_(maxVal), minVal_(minVal), frameNum_(frameNum), updateBackgroundModel_(updateBackgroundModel) + maxFeatures_(maxFeatures), learningRate_(learningRate), numInitializationFrames_(numInitializationFrames), quantizationLevels_(quantizationLevels), + backgroundPrior_(backgroundPrior), decisionThreshold_(decisionThreshold), updateBackgroundModel_(updateBackgroundModel), + maxVal_(maxVal), minVal_(minVal), frameNum_(frameNum) { } @@ -216,7 +202,7 @@ namespace mutable cv::Mat_ fgmask_; mutable cv::Mat_ nfeatures_; - mutable cv::Mat_ colors_; + mutable cv::Mat_ colors_; mutable cv::Mat_ weights_; int maxFeatures_; @@ -234,20 +220,23 @@ namespace void GMG_LoopBody::operator() (const cv::Range& range) const { - typedef int (*func_t)(const void* src_, int x, double minVal, double maxVal, int quantizationLevels); - static const func_t funcs[6][4] = + typedef uint (*func_t)(const void* src_, int x, int cn, double minVal, double maxVal, int quantizationLevels); + static const func_t funcs[] = { - {Quantization::apply, 0, Quantization::apply, Quantization::apply}, - {0,0,0,0}, - {Quantization::apply, 0, Quantization::apply, Quantization::apply}, - {0,0,0,0}, - {0,0,0,0}, - {Quantization::apply, 0, Quantization::apply, Quantization::apply}, + Quantization::apply, + Quantization::apply, + Quantization::apply, + Quantization::apply, + Quantization::apply, + Quantization::apply, + Quantization::apply }; - const func_t func = funcs[frame_.depth()][frame_.channels() - 1]; + const func_t func = funcs[frame_.depth()]; CV_Assert(func != 0); + const int cn = frame_.channels(); + for (int y = range.start, featureIdx = y * frame_.cols; y < range.end; ++y) { const uchar* frame_row = frame_.ptr(y); @@ -257,10 +246,10 @@ namespace for (int x = 0; x < frame_.cols; ++x, ++featureIdx) { int nfeatures = nfeatures_row[x]; - int* colors = colors_[featureIdx]; + uint* colors = colors_[featureIdx]; float* weights = weights_[featureIdx]; - int newFeatureColor = func(frame_row, x, minVal_, maxVal_, quantizationLevels_); + uint newFeatureColor = func(frame_row, x, cn, minVal_, maxVal_, quantizationLevels_); bool isForeground = false; -- 2.7.4