Commit 00d9ef42 authored by jaco's avatar jaco

BING files location update and Start SuBSENSE porting

parent f3cada31
uml @ aa0a3275
Subproject commit 4b13f7c043ee897c429d28066c1f4c487d550b0e
Subproject commit aa0a3275061fc1bc8c0d6464ff21b2c7b41c6179
......@@ -43,20 +43,34 @@
#define __OPENCV_SALIENCY_SPECIALIZED_CLASSES_HPP_
#include "saliencyBaseClasses.hpp"
#include "kyheader.h"
#include "ValStructVec.h"
#include "FilterTIG.h"
#include "BING/kyheader.h"
#include "BING/ValStructVec.h"
#include "BING/FilterTIG.h"
#include "SuBSENSE/BackgroundSubtractorLBSP.h"
#include <cstdio>
#include <string>
#include <iostream>
//! defines the default value for BackgroundSubtractorLBSP::m_fRelLBSPThreshold
#define BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD (0.333f)
//! defines the default value for BackgroundSubtractorLBSP::m_nDescDistThreshold
#define BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD (3)
//! defines the default value for BackgroundSubtractorSuBSENSE::m_nMinColorDistThreshold
#define BGSSUBSENSE_DEFAULT_COLOR_DIST_THRESHOLD (30)
//! defines the default value for BackgroundSubtractorSuBSENSE::m_nBGSamples
#define BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES (50)
//! defines the default value for BackgroundSubtractorSuBSENSE::m_nRequiredBGSamples
#define BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES (2)
//! defines the default value for BackgroundSubtractorSuBSENSE::m_nSamplesForMovingAvgs
#define BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS (25)
namespace cv
{
/************************************ Specific Static Saliency Specialized Classes ************************************/
/**
* \brief Saliency based on algorithms based on [1]
* \brief Saliency based on algorithms described in [1]
* [1]Hou, Xiaodi, and Liqing Zhang. "Saliency detection: A spectral residual approach." Computer Vision and Pattern Recognition, 2007. CVPR'07. IEEE Conference on. IEEE, 2007.
*/
class CV_EXPORTS_W StaticSaliencySpectralResidual : public StaticSaliency
......@@ -67,10 +81,10 @@ class CV_EXPORTS_W StaticSaliencySpectralResidual : public StaticSaliency
StaticSaliencySpectralResidual();
~StaticSaliencySpectralResidual();
typedef cv::Ptr<Size> (cv::Algorithm::*SizeGetter)();
typedef Ptr<Size> (cv::Algorithm::*SizeGetter)();
typedef void (cv::Algorithm::*SizeSetter)( const cv::Ptr<Size> & );
cv::Ptr<Size> getWsize();
Ptr<Size> getWsize();
void setWsize( const cv::Ptr<Size> &arrPtr );
void read( const FileNode& fn );
......@@ -86,7 +100,7 @@ class CV_EXPORTS_W StaticSaliencySpectralResidual : public StaticSaliency
/************************************ Specific Motion Saliency Specialized Classes ************************************/
/**
* \brief Saliency based on algorithms based on [2]
* \brief Saliency based on algorithms described in [2]
* [2] Hofmann, Martin, Philipp Tiefenbacher, and Gerhard Rigoll. "Background segmentation with feedback: The pixel-based adaptive segmenter."
* Computer Vision and Pattern Recognition Workshops (CVPRW), 2012 IEEE Computer Society Conference on. IEEE, 2012.
*/
......@@ -107,11 +121,125 @@ class CV_EXPORTS_W MotionSaliencyPBAS : public MotionSaliency
};
/*!
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 cv::Mat& oInitImg, const std::vector<cv::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()( cv::InputArray image, cv::OutputArray fgmask, double learningRateOverride = 0 );
//! returns a copy of the latest reconstructed background image
void getBackgroundImage( cv::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)
cv::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)
cv::Mat m_oDistThresholdFrame;
//! per-pixel distance variation modulators ('v(x)', relative value used to modulate 'R(x)' and 'T(x)' variations)
cv::Mat m_oVariationModulatorFrame;
//! per-pixel mean distances between consecutive frames ('D_last(x)', used to detect ghosts and high variation regions in the sequence)
cv::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)')
cv::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)
cv::Mat m_oMeanDownSampledLastDistFrame_LT, m_oMeanDownSampledLastDistFrame_ST;
//! per-pixel mean raw segmentation results
cv::Mat m_oMeanRawSegmResFrame_LT, m_oMeanRawSegmResFrame_ST;
//! per-pixel mean final segmentation results
cv::Mat m_oMeanFinalSegmResFrame_LT, m_oMeanFinalSegmResFrame_ST;
//! a lookup map used to keep track of unstable regions (based on segm. noise & local dist. thresholds)
cv::Mat m_oUnstableRegionMask;
//! per-pixel blink detection results ('Z(x)')
cv::Mat m_oBlinksFrame;
//! pre-allocated matrix used to downsample (1/8) the input frame when needed
cv::Mat m_oDownSampledColorFrame;
//! copy of previously used pixel intensities used to calculate 'D_last(x)'
cv::Mat m_oLastColorFrame;
//! copy of previously used descriptors used to calculate 'D_last(x)'
cv::Mat m_oLastDescFrame;
//! the foreground mask generated by the method at [t-1] (without post-proc, used for blinking px detection)
cv::Mat m_oRawFGMask_last;
//! the foreground mask generated by the method at [t-1] (with post-proc)
cv::Mat m_oFGMask_last;
//! pre-allocated CV_8UC1 matrices used to speed up morph ops
cv::Mat m_oFGMask_PreFlood;
cv::Mat m_oFGMask_FloodedHoles;
cv::Mat m_oFGMask_last_dilated;
cv::Mat m_oFGMask_last_dilated_inverted;
cv::Mat m_oRawFGBlinkMask_curr;
cv::Mat m_oRawFGBlinkMask_last;
};
/************************************ Specific Objectness Specialized Classes ************************************/
/**
* \brief Objectness algorithms based on [3]
* [3] Cheng, Ming-Ming, et al. "BING: Binarized normed gradients for objectness estimation at 300fps." IEEE CVPR. 2014.
* \brief Objectness algorithms based on [4]
* [4] Cheng, Ming-Ming, et al. "BING: Binarized normed gradients for objectness estimation at 300fps." IEEE CVPR. 2014.
*/
class CV_EXPORTS_W ObjectnessBING : public Objectness
{
......
#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
virtual 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;
}
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
namespace cv
{
/**
* PBAS Motion Saliency
*/
MotionSaliencyPBAS::MotionSaliencyPBAS()
{
className = "PBAS";
}
MotionSaliencyPBAS::~MotionSaliencyPBAS()
{
}
void MotionSaliencyPBAS::read( const cv::FileNode& /*fn*/)
{
//params.read( fn );
}
void MotionSaliencyPBAS::write( cv::FileStorage& /*fs*/) const
{
//params.write( fs );
}
bool MotionSaliencyPBAS::computeSaliencyImpl( const InputArray /*src*/, OutputArray /*dst*/)
{
return true;
}
}/* namespace cv */
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