1+ #include " HistogramBuilder.h"
2+
3+ using namespace palm ;
4+
5+
6+ HistogramBuilder::HistogramBuilder (cv::Size gridSize, int binCount, bool applyInsidePartitioning)
7+ {
8+ setGridSize (gridSize);
9+ setBinCount (binCount);
10+ setApplyInsidePartitioning (applyInsidePartitioning);
11+ }
12+
13+ void HistogramBuilder::setGridSize (cv::Size gridSize)
14+ {
15+ CV_Assert (gridSize.height > 0 && gridSize.width > 0 );
16+
17+ _gridSize = gridSize;
18+ }
19+
20+ void HistogramBuilder::setApplyInsidePartitioning (bool applyInsidePartitioning)
21+ {
22+ _applyInsidePartitioning = applyInsidePartitioning;
23+ }
24+
25+ void HistogramBuilder::setBinCount (int binCount)
26+ {
27+ CV_Assert (binCount > 1 );
28+
29+ _binCount = binCount;
30+ }
31+
32+ cv::Mat HistogramBuilder::build (const cv::Mat &image)
33+ {
34+ return compute (image, getGridSize (), getBinCount (), isInsidePartitioningApplied ());
35+ }
36+
37+ cv::Mat HistogramBuilder::getGaussianKernel (cv::Size size, double sigma) const
38+ {
39+ CV_Assert (sigma > 0 );
40+
41+ int kernelSize = (size.height % 2 != 0 ) ? size.height : size.height + 1 ;
42+
43+ cv::Mat kernel = cv::getGaussianKernel (kernelSize, sigma);
44+ kernel = kernel * kernel.t ();
45+
46+ if (kernel.size () != size)
47+ {
48+ cv::resize (kernel, kernel, size);
49+ }
50+
51+ return kernel;
52+ }
53+
54+ cv::Mat HistogramBuilder::getRegionHistogram (const cv::Mat ®ion, int binCount, const cv::Mat &gaussianKernel)
55+ {
56+ cv::Mat histogram = cv::Mat::zeros (1 , binCount, CV_64F);
57+
58+ for (int i = 0 ; i < region.rows ; i++)
59+ {
60+ for (int j = 0 ; j < region.cols ; j++)
61+ {
62+ int bin = region.at <uchar>(i, j);
63+ histogram.at <double >(0 , bin) += gaussianKernel.at <double >(i, j);
64+ }
65+ }
66+
67+ histogram = histogram / (cv::norm (histogram, cv::NORM_L2) + std::numeric_limits<double >::epsilon ());
68+
69+ return histogram;
70+ }
71+
72+ int HistogramBuilder::histogramLength ()
73+ {
74+ cv::Size gridSize = getGridSize ();
75+ int binCount = getBinCount ();
76+
77+ int length = gridSize.area () * binCount;
78+ if (isInsidePartitioningApplied ())
79+ {
80+ length += (gridSize.height - 1 ) * (gridSize.width - 1 ) * binCount;
81+ }
82+
83+ return length;
84+ }
85+
86+ cv::Mat HistogramBuilder::compute (const cv::Mat &image, cv::Size gridSize, int binCount, bool applySlidedGrid)
87+ {
88+ CV_Assert (!image.empty () && image.rows > 0 && image.cols > 0 );
89+ CV_Assert (gridSize.width > 0 && gridSize.height > 0 );
90+
91+ cv::Size regionSize = cv::Size (image.cols / gridSize.width , image.rows / gridSize.height );
92+ cv::Mat gaussianKernel = getGaussianKernel (regionSize, 8 );
93+
94+ int descriptorSize = histogramLength ();
95+ cv::Mat histogram (1 , descriptorSize, CV_64F);
96+
97+ // Compute the histograms for the complete grid
98+ for (int i = 0 ; i < gridSize.width ; i++)
99+ {
100+ for (int j = 0 ; j < gridSize.height ; j++)
101+ {
102+ cv::Rect roi = cv::Rect (i * regionSize.width , j * regionSize.height , regionSize.width , regionSize.height );
103+ cv::Mat region = image (roi);
104+
105+ cv::Mat regionHistogram = getRegionHistogram (region, binCount, gaussianKernel);
106+
107+ cv::Rect targetLocation = cv::Rect (binCount * (j * gridSize.width + i), 0 , binCount, 1 );
108+ cv::Mat targetRegion = histogram (targetLocation);
109+ regionHistogram.copyTo (targetRegion);
110+ }
111+ }
112+
113+ if (applySlidedGrid)
114+ {
115+ // Compute the histograms for the slided grid
116+
117+ int numRegionsX = gridSize.width - 1 ;
118+ int numRegionsY = gridSize.height - 1 ;
119+ int numRegions = gridSize.width * gridSize.height ;
120+
121+ for (uint i = 0 ; i < numRegionsX; i++)
122+ {
123+ for (uint j = 0 ; j < numRegionsY; j++)
124+ {
125+ cv::Range rowRange = cv::Range (j * regionSize.height + regionSize.height / 2 ,
126+ (j + 1 ) * regionSize.height + regionSize.height / 2 );
127+ cv::Range colRange = cv::Range (i * regionSize.width + regionSize.width / 2 ,
128+ (i + 1 ) * regionSize.width + regionSize.width / 2 );
129+ cv::Mat region = image (rowRange, colRange).clone ();
130+
131+ cv::Mat regionHistogram = getRegionHistogram (region, binCount, gaussianKernel);
132+
133+ cv::Rect targetLocation = cv::Rect (binCount * (numRegions + j * numRegionsX + i), 0 , binCount, 1 );
134+ cv::Mat targetRegion = histogram (targetLocation);
135+ regionHistogram.copyTo (targetRegion);
136+ }
137+ }
138+ }
139+
140+ return histogram;
141+ }
0 commit comments