Commit b6fc3d81 authored by jaco's avatar jaco

Delete SuBSENSE algorithm (motion saliency) due to license issues

Part of SuBSENSE algorithm is based on ViBe method, that is patented in
Europe ans U.S.
This means that SuBSENSE can not currently be released under the BSD
license. We are trying to resolve the issue.
In waiting, I am forced to remove the algorithm from the "official"
branch on which the pull-request on opencv_contrib will be made . The
code has been moved to an opportune branch (that will not be merged) and
will remain there waiting for this issue to be clarified.
parent 4e478bc0
......@@ -99,119 +99,9 @@ class CV_EXPORTS_W StaticSaliencySpectralResidual : public StaticSaliency
/************************************ Specific Motion Saliency Specialized Classes ************************************/
/*!
Self-Balanced Sensitivity segmenTER (SuBSENSE) foreground-background segmentation algorithm.
Note: both grayscale and RGB/BGR images may be used with this extractor (parameters are adjusted automatically).
For optimal grayscale results, use CV_8UC1 frames instead of CV_8UC3.
For more details on the different parametersor on the algorithm itself, see P.-L. St-Charles et al.,
"Flexible Background Subtraction With Self-Balanced Local Sensitivity", in CVPRW 2014.
This algorithm is currently NOT thread-safe.
*/
class CV_EXPORTS_W MotionSaliencySuBSENSE : public BackgroundSubtractorLBSP, public MotionSaliency
{
public:
//! full constructor
MotionSaliencySuBSENSE( float fRelLBSPThreshold = BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD, size_t nMinDescDistThreshold =
BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD,
size_t nMinColorDistThreshold = BGSSUBSENSE_DEFAULT_COLOR_DIST_THRESHOLD, size_t nBGSamples =
BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES,
size_t nRequiredBGSamples = BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES, size_t nSamplesForMovingAvgs =
BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS );
virtual ~MotionSaliencySuBSENSE();
//! (re)initiaization method; needs to be called before starting background subtraction (note: also reinitializes the keypoints vector)
virtual void initialize( const Mat& oInitImg, const std::vector<KeyPoint>& voKeyPoints );
//! refreshes all samples based on the last analyzed frame
virtual void refreshModel( float fSamplesRefreshFrac );
//! primary model update function; the learning param is used to override the internal learning thresholds (ignored when <= 0)
virtual void operator()( InputArray image, OutputArray fgmask, double learningRateOverride = 0 );
//! returns a copy of the latest reconstructed background image
void getBackgroundImage( OutputArray backgroundImage ) const;
//! turns automatic model reset on or off
void setAutomaticModelReset( bool );
void read( const FileNode& fn );
void write( FileStorage& fs ) const;
protected:
bool computeSaliencyImpl( const InputArray src, OutputArray dst );
AlgorithmInfo* info() const;
//! indicates whether internal structures have already been initialized (LBSP lookup tables, samples, etc.)
bool m_bInitializedInternalStructs;
//! absolute minimal color distance threshold ('R' or 'radius' in the original ViBe paper, used as the default/initial 'R(x)' value here, paired with BackgroundSubtractorLBSP::m_nDescDistThreshold)
const size_t m_nMinColorDistThreshold;
//! number of different samples per pixel/block to be taken from input frames to build the background model (same as 'N' in ViBe/PBAS)
const size_t m_nBGSamples;
//! number of similar samples needed to consider the current pixel/block as 'background' (same as '#_min' in ViBe/PBAS)
const size_t m_nRequiredBGSamples;
//! number of samples to use to compute the learning rate of moving averages
const size_t m_nSamplesForMovingAvgs;
//! current frame index, frame count since last model reset & model reset cooldown counters
size_t m_nFrameIndex, m_nFramesSinceLastReset, m_nModelResetCooldown;
//! last calculated non-zero desc ratio
float m_fLastNonZeroDescRatio;
//! specifies whether automatic model reset is enabled or not
bool m_bAutoModelResetEnabled;
//! specifies whether Tmin/Tmax scaling is enabled or not
bool m_bLearningRateScalingEnabled;
//! current learning rate caps
float m_fCurrLearningRateLowerCap, m_fCurrLearningRateUpperCap;
//! current kernel size for median blur post-proc filtering
int m_nMedianBlurKernelSize;
//! specifies the px update spread range
bool m_bUse3x3Spread;
//! specifies the downsampled frame size (used for cam motion analysis)
Size m_oDownSampledFrameSize;
//! background model pixel color intensity samples (equivalent to 'B(x)' in PBAS, but also paired with BackgroundSubtractorLBSP::m_voBGDescSamples to create our complete model)
std::vector<Mat> m_voBGColorSamples;
//! per-pixel update rates ('T(x)' in PBAS, which contains pixel-level 'sigmas', as referred to in ViBe)
Mat m_oUpdateRateFrame;
//! per-pixel distance thresholds (equivalent to 'R(x)' in PBAS, but used as a relative value to determine both intensity and descriptor variation thresholds)
Mat m_oDistThresholdFrame;
//! per-pixel distance variation modulators ('v(x)', relative value used to modulate 'R(x)' and 'T(x)' variations)
Mat m_oVariationModulatorFrame;
//! per-pixel mean distances between consecutive frames ('D_last(x)', used to detect ghosts and high variation regions in the sequence)
Mat m_oMeanLastDistFrame;
//! per-pixel mean minimal distances from the model ('D_min(x)' in PBAS, used to control variation magnitude and direction of 'T(x)' and 'R(x)')
Mat m_oMeanMinDistFrame_LT, m_oMeanMinDistFrame_ST;
//! per-pixel mean downsampled distances between consecutive frames (used to analyze camera movement and control max learning rates globally)
Mat m_oMeanDownSampledLastDistFrame_LT, m_oMeanDownSampledLastDistFrame_ST;
//! per-pixel mean raw segmentation results
Mat m_oMeanRawSegmResFrame_LT, m_oMeanRawSegmResFrame_ST;
//! per-pixel mean final segmentation results
Mat m_oMeanFinalSegmResFrame_LT, m_oMeanFinalSegmResFrame_ST;
//! a lookup map used to keep track of unstable regions (based on segm. noise & local dist. thresholds)
Mat m_oUnstableRegionMask;
//! per-pixel blink detection results ('Z(x)')
Mat m_oBlinksFrame;
//! pre-allocated matrix used to downsample (1/8) the input frame when needed
Mat m_oDownSampledColorFrame;
//! copy of previously used pixel intensities used to calculate 'D_last(x)'
Mat m_oLastColorFrame;
//! copy of previously used descriptors used to calculate 'D_last(x)'
Mat m_oLastDescFrame;
//! the foreground mask generated by the method at [t-1] (without post-proc, used for blinking px detection)
Mat m_oRawFGMask_last;
//! the foreground mask generated by the method at [t-1] (with post-proc)
Mat m_oFGMask_last;
//! pre-allocated CV_8UC1 matrices used to speed up morph ops
Mat m_oFGMask_PreFlood;
Mat m_oFGMask_FloodedHoles;
Mat m_oFGMask_last_dilated;
Mat m_oFGMask_last_dilated_inverted;
Mat m_oRawFGBlinkMask_curr;
Mat m_oRawFGBlinkMask_last;
};
/************************************ Specific Objectness Specialized Classes ************************************/
......
#include "BackgroundSubtractorLBSP.h"
#include "DistanceUtils.h"
#include "RandUtils.h"
#include <iostream>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iomanip>
#include <exception>
BackgroundSubtractorLBSP::BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nDescDistThreshold, size_t nLBSPThresholdOffset)
: nDebugCoordX(0),nDebugCoordY(0)
,m_nKeyPoints(0)
,m_nImgChannels(0)
,m_nImgType(0)
,m_nDescDistThreshold(nDescDistThreshold)
,m_nLBSPThresholdOffset(nLBSPThresholdOffset)
,m_fRelLBSPThreshold(fRelLBSPThreshold)
,m_bInitialized(false) {
CV_Assert(m_fRelLBSPThreshold>=0);
}
BackgroundSubtractorLBSP::~BackgroundSubtractorLBSP() {}
void BackgroundSubtractorLBSP::initialize(const cv::Mat& oInitImg) {
this->initialize(oInitImg,std::vector<cv::KeyPoint>());
}
//cv::AlgorithmInfo* BackgroundSubtractorLBSP::info() const {
// //return nullptr;
//}
void BackgroundSubtractorLBSP::getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const {
CV_Assert(LBSP::DESC_SIZE==2);
CV_Assert(m_bInitialized);
cv::Mat oAvgBGDesc = cv::Mat::zeros(m_oImgSize,CV_32FC((int)m_nImgChannels));
for(size_t n=0; n<m_voBGDescSamples.size(); ++n) {
for(int y=0; y<m_oImgSize.height; ++y) {
for(int x=0; x<m_oImgSize.width; ++x) {
const size_t idx_ndesc = m_voBGDescSamples[n].step.p[0]*y + m_voBGDescSamples[n].step.p[1]*x;
const size_t idx_flt32 = idx_ndesc*2;
float* oAvgBgDescPtr = (float*)(oAvgBGDesc.data+idx_flt32);
const ushort* const oBGDescPtr = (ushort*)(m_voBGDescSamples[n].data+idx_ndesc);
for(size_t c=0; c<m_nImgChannels; ++c)
oAvgBgDescPtr[c] += ((float)oBGDescPtr[c])/m_voBGDescSamples.size();
}
}
}
oAvgBGDesc.convertTo(backgroundDescImage,CV_16U);
}
std::vector<cv::KeyPoint> BackgroundSubtractorLBSP::getBGKeyPoints() const {
return m_voKeyPoints;
}
void BackgroundSubtractorLBSP::setBGKeyPoints(std::vector<cv::KeyPoint>& keypoints) {
LBSP::validateKeyPoints(keypoints,m_oImgSize);
CV_Assert(!keypoints.empty());
m_voKeyPoints = keypoints;
m_nKeyPoints = keypoints.size();
}
#pragma once
#include <opencv2/features2d.hpp>
//#include <opencv2/video/background_segm.hpp>
#include "LBSP.h"
/*!
Local Binary Similarity Pattern (LBSP) foreground-background segmentation algorithm (abstract version).
For more details on the different parameters, see P.-L. St-Charles and G.-A. Bilodeau, "Improving Background
Subtraction using Local Binary Similarity Patterns", in WACV 2014, or G.-A. Bilodeau et al, "Change Detection
in Feature Space Using Local Binary Similarity Patterns", in CRV 2013.
This algorithm is currently NOT thread-safe.
*/
class BackgroundSubtractorLBSP /* : public cv::BackgroundSubtractor */
{
public:
//! full constructor
BackgroundSubtractorLBSP( float fRelLBSPThreshold, size_t nDescDistThreshold, size_t nLBSPThresholdOffset = 0 );
//! default destructor
virtual ~BackgroundSubtractorLBSP();
//! (re)initiaization method; needs to be called before starting background subtraction
virtual void initialize( const cv::Mat& oInitImg );
//! (re)initiaization method; needs to be called before starting background subtraction (note: also reinitializes the keypoints vector)
virtual void initialize( const cv::Mat& oInitImg, const std::vector<cv::KeyPoint>& voKeyPoints )=0;
//! primary model update function; the learning param is used to override the internal learning speed (ignored when <= 0)
virtual void operator()( cv::InputArray image, cv::OutputArray fgmask, double learningRate = 0 )=0;
//! unused, always returns nullptr
cv::AlgorithmInfo* info() const;
//! returns a copy of the latest reconstructed background descriptors image
virtual void getBackgroundDescriptorsImage( cv::OutputArray backgroundDescImage ) const;
//! returns the keypoints list used for descriptor extraction (note: by default, these are generated from the DenseFeatureDetector class, and the border points are removed)
virtual std::vector<cv::KeyPoint> getBGKeyPoints() const;
//! sets the keypoints to be used for descriptor extraction, effectively setting the BGModel ROI (note: this function will remove all border keypoints)
virtual void setBGKeyPoints( std::vector<cv::KeyPoint>& keypoints );
// ######## DEBUG PURPOSES ONLY ##########
int nDebugCoordX, nDebugCoordY;
protected:
//! background model descriptors samples (tied to m_voKeyPoints but shaped like the input frames)
std::vector<cv::Mat> m_voBGDescSamples;
//! background model keypoints used for LBSP descriptor extraction (specific to the input image size)
std::vector<cv::KeyPoint> m_voKeyPoints;
//! defines the current number of used keypoints (always tied to m_voKeyPoints)
size_t m_nKeyPoints;
//! input image size
cv::Size m_oImgSize;
//! input image channel size
size_t m_nImgChannels;
//! input image type
int m_nImgType;
//! absolute descriptor distance threshold
const size_t m_nDescDistThreshold;
//! LBSP internal threshold offset value -- used to reduce texture noise in dark regions
const size_t m_nLBSPThresholdOffset;
//! LBSP relative internal threshold (kept here since we don't keep an LBSP object)
const float m_fRelLBSPThreshold;
//! pre-allocated internal LBSP threshold values for all possible 8-bit intensity values
size_t m_anLBSPThreshold_8bitLUT[UCHAR_MAX + 1];
//! defines whether or not the subtractor is fully initialized
bool m_bInitialized;
};
#pragma once
#include <opencv2/core/types_c.h>
//! computes the absolute difference of two unsigned char values
static inline size_t absdiff_uchar(uchar a, uchar b) {
return (size_t)abs((int)a-(int)b); // should return the same as (a<b?b-a:a-b), but faster when properly optimized
}
//! computes the L1 distance between two unsigned char vectors (RGB)
static inline size_t L1dist_uchar(const uchar* a, const uchar* b) {
return absdiff_uchar(a[0],b[0])+absdiff_uchar(a[1],b[1])+absdiff_uchar(a[2],b[2]);
}
//! computes the color distortion between two unsigned char vectors (RGB)
static inline size_t cdist_uchar(const uchar* curr, const uchar* bg) {
size_t curr_int_sqr = curr[0]*curr[0] + curr[1]*curr[1] + curr[2]*curr[2];
if(bg[0] || bg[1] || bg[2]) {
size_t bg_int_sqr = bg[0]*bg[0] + bg[1]*bg[1] + bg[2]*bg[2];
float mix_int_sqr = std::pow((float)(curr[0]*bg[0] + curr[1]*bg[1] + curr[2]*bg[2]),2);
return (size_t)sqrt(curr_int_sqr-(mix_int_sqr/bg_int_sqr));
}
else
return (size_t)sqrt((float)curr_int_sqr);
}
//! computes the L1 distance between two opencv unsigned char vectors (RGB)
static inline size_t L1dist_vec3b(const cv::Vec3b& a, const cv::Vec3b& b) {
const uchar a_array[3] = {a[0],a[1],a[2]};
const uchar b_array[3] = {b[0],b[1],b[2]};
return L1dist_uchar(a_array,b_array);
}
//! computes the squared L2 distance between two unsigned char vectors (RGB)
static inline size_t L2sqrdist_uchar(const uchar* a, const uchar* b) {
return (absdiff_uchar(a[0],b[0])^2)+(absdiff_uchar(a[1],b[1])^2)+(absdiff_uchar(a[2],b[2])^2);
}
//! computes the L2 distance between two unsigned char vectors (RGB)
static inline float L2dist_uchar(const uchar* a, const uchar* b) {
return sqrt((float)L2sqrdist_uchar(a,b));
}
//! computes the squared L2 distance between two opencv unsigned char vectors (RGB)
static inline size_t L2sqrdist_vec3b(const cv::Vec3b& a, const cv::Vec3b& b) {
const uchar a_array[3] = {a[0],a[1],a[2]};
const uchar b_array[3] = {b[0],b[1],b[2]};
return L2sqrdist_uchar(a_array,b_array);
}
//! computes the squared L2 distance between two opencv unsigned char vectors (RGB)
static inline float L2dist_vec3b(const cv::Vec3b& a, const cv::Vec3b& b) {
return sqrt((float)L2sqrdist_vec3b(a,b));
}
//! popcount LUT for 8bit vectors
static const uchar popcount_LUT8[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
};
//! computes the population count of a 16bit vector using an 8bit popcount LUT (min=0, max=48)
static inline uchar popcount_ushort_8bitsLUT(ushort x) {
return popcount_LUT8[(uchar)x] + popcount_LUT8[(uchar)(x>>8)];
}
//! computes the population count of 3x16bit vectors using an 8bit popcount LUT (min=0, max=48)
static inline uchar popcount_ushort_8bitsLUT(const ushort* x) {
return popcount_LUT8[(uchar)x[0]] + popcount_LUT8[(uchar)(x[0]>>8)]
+ popcount_LUT8[(uchar)x[1]] + popcount_LUT8[(uchar)(x[1]>>8)]
+ popcount_LUT8[(uchar)x[2]] + popcount_LUT8[(uchar)(x[2]>>8)];
}
//! computes the hamming distance between two 16bit vectors (min=0, max=16)
static inline size_t hdist_ushort_8bitLUT(ushort a, ushort b) {
return popcount_ushort_8bitsLUT(a^b);
}
//! computes the sum of hamming distances between two 3x16 bits vectors (min=0, max=48)
static inline size_t hdist_ushort_8bitLUT(const ushort* a, const ushort* b) {
return popcount_ushort_8bitsLUT(a[0]^b[0])+popcount_ushort_8bitsLUT(a[1]^b[1])+popcount_ushort_8bitsLUT(a[2]^b[2]);
}
//! computes the gradient magnitude distance between two 16 bits vectors (min=0, max=16)
static inline size_t gdist_ushort_8bitLUT(ushort a, ushort b) {
return (size_t)abs((int)popcount_ushort_8bitsLUT(a)-(int)popcount_ushort_8bitsLUT(b));
}
//! computes the sum of gradient magnitude distances between two 3x16 bits vectors (min=0, max=48)
static inline size_t gdist_ushort_8bitLUT(const ushort* a, const ushort* b) {
return (size_t)abs((int)popcount_ushort_8bitsLUT(a)-(int)popcount_ushort_8bitsLUT(b));
}
This diff is collapsed.
#pragma once
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include "DistanceUtils.h"
/*!
Local Binary Similarity Pattern (LBSP) feature extractor
Note 1: both grayscale and RGB/BGR images may be used with this extractor.
Note 2: using LBSP::compute2(...) is logically equivalent to using LBSP::compute(...) followed by LBSP::reshapeDesc(...).
For more details on the different parameters, see G.-A. Bilodeau et al, "Change Detection in Feature Space Using Local
Binary Similarity Patterns", in CRV 2013.
This algorithm is currently NOT thread-safe.
*/
class LBSP : public cv::DescriptorExtractor {
public:
//! constructor 1, threshold = absolute intensity 'similarity' threshold used when computing comparisons
LBSP(size_t nThreshold);
//! constructor 2, threshold = relative intensity 'similarity' threshold used when computing comparisons
LBSP(float fRelThreshold, size_t nThresholdOffset=0);
//! default destructor
virtual ~LBSP();
//! loads extractor params from the specified file node @@@@ not impl
virtual void read(const cv::FileNode&);
//! writes extractor params to the specified file storage @@@@ not impl
virtual void write(cv::FileStorage&) const;
//! sets the 'reference' image to be used for inter-frame comparisons (note: if no image is set or if the image is empty, the algorithm will default back to intra-frame comparisons)
virtual void setReference(const cv::Mat&);
//! returns the current descriptor size, in bytes
virtual int descriptorSize() const;
//! returns the current descriptor data type
virtual int descriptorType() const;
//! returns whether this extractor is using a relative threshold or not
virtual bool isUsingRelThreshold() const;
//! returns the current relative threshold used for comparisons (-1 = invalid/not used)
virtual float getRelThreshold() const;
//! returns the current absolute threshold used for comparisons (-1 = invalid/not used)
virtual size_t getAbsThreshold() const;
//! similar to DescriptorExtractor::compute(const cv::Mat& image, ...), but in this case, the descriptors matrix has the same shape as the input matrix (possibly slower, but the result can be displayed)
void compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
//! batch version of LBSP::compute2(const cv::Mat& image, ...), also similar to DescriptorExtractor::compute(const std::vector<cv::Mat>& imageCollection, ...)
void compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const;
// utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel version)
inline static void computeGrayscaleDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _t, ushort& _res) {
CV_DbgAssert(!oInputImg.empty());
CV_DbgAssert(oInputImg.type()==CV_8UC1);
CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
const size_t _step_row = oInputImg.step.p[0];
const uchar* const _data = oInputImg.data;
#include "LBSP_16bits_dbcross_1ch.i"
}
// utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref, const int _x, const int _y, const size_t* const _t, ushort* _res) {
CV_DbgAssert(!oInputImg.empty());
CV_DbgAssert(oInputImg.type()==CV_8UC3);
CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
const size_t _step_row = oInputImg.step.p[0];
const uchar* const _data = oInputImg.data;
#include "LBSP_16bits_dbcross_3ch3t.i"
}
// utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref, const int _x, const int _y, const size_t _t, ushort* _res) {
CV_DbgAssert(!oInputImg.empty());
CV_DbgAssert(oInputImg.type()==CV_8UC3);
CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
const size_t _step_row = oInputImg.step.p[0];
const uchar* const _data = oInputImg.data;
#include "LBSP_16bits_dbcross_3ch1t.i"
}
// utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel-RGB version)
inline static void computeSingleRGBDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _c, const size_t _t, ushort& _res) {
CV_DbgAssert(!oInputImg.empty());
CV_DbgAssert(oInputImg.type()==CV_8UC3 && _c<3);
CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
const size_t _step_row = oInputImg.step.p[0];
const uchar* const _data = oInputImg.data;
#include "LBSP_16bits_dbcross_s3ch.i"
}
//! utility function, used to reshape a descriptors matrix to its input image size via their keypoint locations
static void reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput);
//! utility function, used to illustrate the difference between two descriptor images
static void calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels=false);
//! utility function, used to filter out bad keypoints that would trigger out of bounds error because they're too close to the image border
static void validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize);
//! utility, specifies the pixel size of the pattern used (width and height)
static const size_t PATCH_SIZE = 5;
//! utility, specifies the number of bytes per descriptor (should be the same as calling 'descriptorSize()')
static const size_t DESC_SIZE = 2;
protected:
//! classic 'compute' implementation, based on the regular DescriptorExtractor::computeImpl arguments & expected output
virtual void computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
const bool m_bOnlyUsingAbsThreshold;
const float m_fRelThreshold;
const size_t m_nThreshold;
cv::Mat m_oRefImage;
};
// note: this is the LBSP 16 bit double-cross single channel pattern as used in
// the original article by G.-A. Bilodeau et al.
//
// O O O 4 .. 3 .. 6
// O O O .. 15 8 13 ..
// O O X O O => 0 9 X 11 1
// O O O .. 12 10 14 ..
// O O O 7 .. 2 .. 5
//
// must be defined externally:
// _t (size_t, absolute threshold used for comparisons)
// _ref (uchar, 'central' value used for comparisons)
// _data (uchar*, single-channel data to be covered by the pattern)
// _y (int, pattern rows location in the image data)
// _x (int, pattern cols location in the image data)
// _step_row (size_t, step size between rows, including padding)
// _res (ushort, 16 bit result vector)
// absdiff_uchar (function, returns the absolute difference between two uchars)
#ifdef _val
#error "definitions clash detected"
#else
#define _val(x,y) _data[_step_row*(_y+y)+_x+x]
#endif
_res= ((absdiff_uchar(_val(-1, 1),_ref) > _t) << 15)
+ ((absdiff_uchar(_val( 1,-1),_ref) > _t) << 14)
+ ((absdiff_uchar(_val( 1, 1),_ref) > _t) << 13)
+ ((absdiff_uchar(_val(-1,-1),_ref) > _t) << 12)
+ ((absdiff_uchar(_val( 1, 0),_ref) > _t) << 11)
+ ((absdiff_uchar(_val( 0,-1),_ref) > _t) << 10)
+ ((absdiff_uchar(_val(-1, 0),_ref) > _t) << 9)
+ ((absdiff_uchar(_val( 0, 1),_ref) > _t) << 8)
+ ((absdiff_uchar(_val(-2,-2),_ref) > _t) << 7)
+ ((absdiff_uchar(_val( 2, 2),_ref) > _t) << 6)
+ ((absdiff_uchar(_val( 2,-2),_ref) > _t) << 5)
+ ((absdiff_uchar(_val(-2, 2),_ref) > _t) << 4)
+ ((absdiff_uchar(_val( 0, 2),_ref) > _t) << 3)
+ ((absdiff_uchar(_val( 0,-2),_ref) > _t) << 2)
+ ((absdiff_uchar(_val( 2, 0),_ref) > _t) << 1)
+ ((absdiff_uchar(_val(-2, 0),_ref) > _t));
#undef _val
\ No newline at end of file
// note: this is the LBSP 16 bit double-cross indiv RGB pattern as used in
// the original article by G.-A. Bilodeau et al.
//
// O O O 4 .. 3 .. 6
// O O O .. 15 8 13 ..
// O O X O O => 0 9 X 11 1
// O O O .. 12 10 14 ..
// O O O 7 .. 2 .. 5
// 3x 3x
//
// must be defined externally:
// _t (size_t, absolute threshold used for comparisons)
// _ref (uchar[3], 'central' values used for comparisons)
// _data (uchar*, triple-channel data to be covered by the pattern)
// _y (int, pattern rows location in the image data)
// _x (int, pattern cols location in the image data)
// _step_row (size_t, step size between rows, including padding)
// _res (ushort[3], 16 bit result vectors vector)
// absdiff_uchar (function, returns the absolute difference between two uchars)
#ifdef _val
#error "definitions clash detected"
#else
#define _val(x,y,n) _data[_step_row*(_y+y)+3*(_x+x)+n]
#endif
for(int n=0; n<3; ++n) {
_res[n] = ((absdiff_uchar(_val(-1, 1, n),_ref[n]) > _t) << 15)
+ ((absdiff_uchar(_val( 1,-1, n),_ref[n]) > _t) << 14)
+ ((absdiff_uchar(_val( 1, 1, n),_ref[n]) > _t) << 13)
+ ((absdiff_uchar(_val(-1,-1, n),_ref[n]) > _t) << 12)
+ ((absdiff_uchar(_val( 1, 0, n),_ref[n]) > _t) << 11)
+ ((absdiff_uchar(_val( 0,-1, n),_ref[n]) > _t) << 10)
+ ((absdiff_uchar(_val(-1, 0, n),_ref[n]) > _t) << 9)
+ ((absdiff_uchar(_val( 0, 1, n),_ref[n]) > _t) << 8)
+ ((absdiff_uchar(_val(-2,-2, n),_ref[n]) > _t) << 7)
+ ((absdiff_uchar(_val( 2, 2, n),_ref[n]) > _t) << 6)
+ ((absdiff_uchar(_val( 2,-2, n),_ref[n]) > _t) << 5)
+ ((absdiff_uchar(_val(-2, 2, n),_ref[n]) > _t) << 4)
+ ((absdiff_uchar(_val( 0, 2, n),_ref[n]) > _t) << 3)
+ ((absdiff_uchar(_val( 0,-2, n),_ref[n]) > _t) << 2)
+ ((absdiff_uchar(_val( 2, 0, n),_ref[n]) > _t) << 1)
+ ((absdiff_uchar(_val(-2, 0, n),_ref[n]) > _t));
}
#undef _val
// note: this is the LBSP 16 bit double-cross indiv RGB pattern as used in
// the original article by G.-A. Bilodeau et al.
//
// O O O 4 .. 3 .. 6
// O O O .. 15 8 13 ..
// O O X O O => 0 9 X 11 1
// O O O .. 12 10 14 ..
// O O O 7 .. 2 .. 5
// 3x 3x
//
// must be defined externally:
// _t (size_t[3], absolute thresholds used for comparisons)
// _ref (uchar[3], 'central' values used for comparisons)
// _data (uchar*, triple-channel data to be covered by the pattern)
// _y (int, pattern rows location in the image data)
// _x (int, pattern cols location in the image data)
// _step_row (size_t, step size between rows, including padding)
// _res (ushort[3], 16 bit result vectors vector)
// absdiff_uchar (function, returns the absolute difference between two uchars)
#ifdef _val
#error "definitions clash detected"
#else
#define _val(x,y,n) _data[_step_row*(_y+y)+3*(_x+x)+n]
#endif
for(int n=0; n<3; ++n) {
_res[n] = ((absdiff_uchar(_val(-1, 1, n),_ref[n]) > _t[n]) << 15)
+ ((absdiff_uchar(_val( 1,-1, n),_ref[n]) > _t[n]) << 14)
+ ((absdiff_uchar(_val( 1, 1, n),_ref[n]) > _t[n]) << 13)
+ ((absdiff_uchar(_val(-1,-1, n),_ref[n]) > _t[n]) << 12)
+ ((absdiff_uchar(_val( 1, 0, n),_ref[n]) > _t[n]) << 11)
+ ((absdiff_uchar(_val( 0,-1, n),_ref[n]) > _t[n]) << 10)
+ ((absdiff_uchar(_val(-1, 0, n),_ref[n]) > _t[n]) << 9)
+ ((absdiff_uchar(_val( 0, 1, n),_ref[n]) > _t[n]) << 8)
+ ((absdiff_uchar(_val(-2,-2, n),_ref[n]) > _t[n]) << 7)
+ ((absdiff_uchar(_val( 2, 2, n),_ref[n]) > _t[n]) << 6)
+ ((absdiff_uchar(_val( 2,-2, n),_ref[n]) > _t[n]) << 5)
+ ((absdiff_uchar(_val(-2, 2, n),_ref[n]) > _t[n]) << 4)
+ ((absdiff_uchar(_val( 0, 2, n),_ref[n]) > _t[n]) << 3)
+ ((absdiff_uchar(_val( 0,-2, n),_ref[n]) > _t[n]) << 2)
+ ((absdiff_uchar(_val( 2, 0, n),_ref[n]) > _t[n]) << 1)
+ ((absdiff_uchar(_val(-2, 0, n),_ref[n]) > _t[n]));
}
#undef _val
// note: this is the LBSP 16 bit double-cross indiv RGB pattern as used in
// the original article by G.-A. Bilodeau et al.
//
// O O O 4 .. 3 .. 6
// O O O .. 15 8 13 ..
// O O X O O => 0 9 X 11 1
// O O O .. 12 10 14 ..
// O O O 7 .. 2 .. 5
// (single/3x) (single/3x)
//
// must be defined externally:
// _t (size_t, absolute threshold used for comparisons)
// _ref (uchar, 'central' value used for comparisons)
// _data (uchar*, triple-channel data to be covered by the pattern)
// _y (int, pattern rows location in the image data)
// _x (int, pattern cols location in the image data)
// _c (size_t, pattern channel location in the image data)
// _step_row (size_t, step size between rows, including padding)
// _res (ushort, 16 bit result vector)
// absdiff_uchar (function, returns the absolute difference between two uchars)
#ifdef _val
#error "definitions clash detected"
#else
#define _val(x,y,n) _data[_step_row*(_y+y)+3*(_x+x)+n]
#endif
_res = ((absdiff_uchar(_val(-1, 1, _c),_ref) > _t) << 15)
+ ((absdiff_uchar(_val( 1,-1, _c),_ref) > _t) << 14)
+ ((absdiff_uchar(_val( 1, 1, _c),_ref) > _t) << 13)
+ ((absdiff_uchar(_val(-1,-1, _c),_ref) > _t) << 12)
+ ((absdiff_uchar(_val( 1, 0, _c),_ref) > _t) << 11)
+ ((absdiff_uchar(_val( 0,-1, _c),_ref) > _t) << 10)
+ ((absdiff_uchar(_val(-1, 0, _c),_ref) > _t) << 9)
+ ((absdiff_uchar(_val( 0, 1, _c),_ref) > _t) << 8)
+ ((absdiff_uchar(_val(-2,-2, _c),_ref) > _t) << 7)
+ ((absdiff_uchar(_val( 2, 2, _c),_ref) > _t) << 6)
+ ((absdiff_uchar(_val( 2,-2, _c),_ref) > _t) << 5)
+ ((absdiff_uchar(_val(-2, 2, _c),_ref) > _t) << 4)
+ ((absdiff_uchar(_val( 0, 2, _c),_ref) > _t) << 3)
+ ((absdiff_uchar(_val( 0,-2, _c),_ref) > _t) << 2)
+ ((absdiff_uchar(_val( 2, 0, _c),_ref) > _t) << 1)
+ ((absdiff_uchar(_val(-2, 0, _c),_ref) > _t));
#undef _val
\ No newline at end of file
#pragma once
/*// gaussian 3x3 pattern, based on 'floor(fspecial('gaussian', 3, 1)*256)'
static const int s_nSamplesInitPatternWidth = 3;
static const int s_nSamplesInitPatternHeight = 3;
static const int s_nSamplesInitPatternTot = 256;
static const int s_anSamplesInitPattern[s_nSamplesInitPatternHeight][s_nSamplesInitPatternWidth] = {
{19, 32, 19,},
{32, 52, 32,},
{19, 32, 19,},
};*/
// gaussian 7x7 pattern, based on 'floor(fspecial('gaussian',7,1)*4096)'
static const int s_nSamplesInitPatternWidth = 7;
static const int s_nSamplesInitPatternHeight = 7;
static const int s_nSamplesInitPatternTot = 4096;
static const int s_anSamplesInitPattern[s_nSamplesInitPatternHeight][s_nSamplesInitPatternWidth] = {
{0, 0, 4, 7, 4, 0, 0,},
{0, 11, 53, 88, 53, 11, 0,},
{4, 53, 240, 399, 240, 53, 4,},
{7, 88, 399, 660, 399, 88, 7,},
{4, 53, 240, 399, 240, 53, 4,},
{0, 11, 53, 88, 53, 11, 0,},
{0, 0, 4, 7, 4, 0, 0,},
};
//! returns a random init/sampling position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
static inline void getRandSamplePosition(int& x_sample, int& y_sample, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
int r = 1+rand()%s_nSamplesInitPatternTot;
for(x_sample=0; x_sample<s_nSamplesInitPatternWidth; ++x_sample) {
for(y_sample=0; y_sample<s_nSamplesInitPatternHeight; ++y_sample) {
r -= s_anSamplesInitPattern[y_sample][x_sample];
if(r<=0)
goto stop;
}
}
stop:
x_sample += x_orig-s_nSamplesInitPatternWidth/2;
y_sample += y_orig-s_nSamplesInitPatternHeight/2;
if(x_sample<border)
x_sample = border;
else if(x_sample>=imgsize.width-border)
x_sample = imgsize.width-border-1;
if(y_sample<border)
y_sample = border;
else if(y_sample>=imgsize.height-border)
y_sample = imgsize.height-border-1;
}
// simple 8-connected (3x3) neighbors pattern
static const int s_anNeighborPatternSize_3x3 = 8;
static const int s_anNeighborPattern_3x3[8][2] = {
{-1, 1}, { 0, 1}, { 1, 1},
{-1, 0}, { 1, 0},
{-1,-1}, { 0,-1}, { 1,-1},
};
//! returns a random neighbor position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
static inline void getRandNeighborPosition_3x3(int& x_neighbor, int& y_neighbor, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
int r = rand()%s_anNeighborPatternSize_3x3;
x_neighbor = x_orig+s_anNeighborPattern_3x3[r][0];
y_neighbor = y_orig+s_anNeighborPattern_3x3[r][1];
if(x_neighbor<border)
x_neighbor = border;
else if(x_neighbor>=imgsize.width-border)
x_neighbor = imgsize.width-border-1;
if(y_neighbor<border)
y_neighbor = border;
else if(y_neighbor>=imgsize.height-border)
y_neighbor = imgsize.height-border-1;
}
// 5x5 neighbors pattern
static const int s_anNeighborPatternSize_5x5 = 24;
static const int s_anNeighborPattern_5x5[24][2] = {
{-2, 2}, {-1, 2}, { 0, 2}, { 1, 2}, { 2, 2},
{-2, 1}, {-1, 1}, { 0, 1}, { 1, 1}, { 2, 1},
{-2, 0}, {-1, 0}, { 1, 0}, { 2, 0},
{-2,-1}, {-1,-1}, { 0,-1}, { 1,-1}, { 2,-1},
{-2,-2}, {-1,-2}, { 0,-2}, { 1,-2}, { 2,-2},
};
//! returns a random neighbor position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
static inline void getRandNeighborPosition_5x5(int& x_neighbor, int& y_neighbor, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
int r = rand()%s_anNeighborPatternSize_5x5;
x_neighbor = x_orig+s_anNeighborPattern_5x5[r][0];
y_neighbor = y_orig+s_anNeighborPattern_5x5[r][1];
if(x_neighbor<border)
x_neighbor = border;
else if(x_neighbor>=imgsize.width-border)
x_neighbor = imgsize.width-border-1;
if(y_neighbor<border)
y_neighbor = border;
else if(y_neighbor>=imgsize.height-border)
y_neighbor = imgsize.height-border-1;
}
......@@ -52,7 +52,7 @@ CV_INIT_ALGORITHM(
reinterpret_cast<SizeGetter>( &StaticSaliencySpectralResidual::getWsize ),
reinterpret_cast<SizeSetter>( &StaticSaliencySpectralResidual::setWsize ) ) );
CV_INIT_ALGORITHM( MotionSaliencySuBSENSE, "SALIENCY.SuBSENSE", );
//CV_INIT_ALGORITHM( MotionSaliencySuBSENSE, "SALIENCY.SuBSENSE", );
CV_INIT_ALGORITHM(
ObjectnessBING, "SALIENCY.BING",
......@@ -62,7 +62,7 @@ bool initModule_saliency( void )
{
bool all = true;
all &= !StaticSaliencySpectralResidual_info_auto.name().empty();
all &= !MotionSaliencySuBSENSE_info_auto.name().empty();
//all &= !MotionSaliencySuBSENSE_info_auto.name().empty();
all &= !ObjectnessBING_info_auto.name().empty();
return all;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment