forked from Smorodov/Multitarget-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLBSP.h
More file actions
118 lines (105 loc) · 7.08 KB
/
LBSP.h
File metadata and controls
118 lines (105 loc) · 7.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#pragma once
#include <opencv2/core.hpp>
#include <opencv2/features2d/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 final : 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() = default;
//! 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 function, used to filter out bad pixels in a ROI that would trigger out of bounds error because they're too close to the image border
static void validateROI(cv::Mat& oROI);
//! utility, specifies the pixel size of the pattern used (width and height)
static constexpr size_t PATCH_SIZE = 5;
//! utility, specifies the number of bytes per descriptor (should be the same as calling 'descriptorSize()')
static constexpr 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;
};