Skip to content

Commit bc42c9d

Browse files
committed
Source files are added
1 parent 7cbdb7a commit bc42c9d

12 files changed

+1069
-0
lines changed

CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
cmake_minimum_required(VERSION 3.7)
2+
project(PALM)
3+
4+
set(CMAKE_CXX_STANDARD 11)
5+
6+
# Import OpenCV
7+
find_package(OpenCV)
8+
if (OpenCV_FOUND)
9+
include_directories(${OpenCV_INCLUDE_DIRS})
10+
endif ()
11+
12+
include_directories(PALM)
13+
14+
set(SOURCES
15+
PALM/HistogramBuilder.cpp
16+
PALM/HistogramBuilder.h
17+
PALM/IlluminationFilter.cpp
18+
PALM/IlluminationFilter.h
19+
PALM/PALM.cpp
20+
PALM/PALM.h
21+
PALM/PatternImageExtractor.cpp
22+
PALM/PatternImageExtractor.h
23+
PALM/ZernikeBaseGenerator.cpp
24+
PALM/ZernikeBaseGenerator.h
25+
)
26+
27+
add_executable(PALM main.cpp ${SOURCES})
28+
target_link_libraries(PALM ${OpenCV_LIBS})

PALM/HistogramBuilder.cpp

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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 &region, 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+
}

PALM/HistogramBuilder.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef PALM_HISTOGRAMBUILDER_H
2+
#define PALM_HISTOGRAMBUILDER_H
3+
4+
#include <opencv2/core.hpp>
5+
#include <opencv2/imgproc.hpp>
6+
7+
8+
namespace palm
9+
{
10+
class HistogramBuilder
11+
{
12+
public:
13+
HistogramBuilder(cv::Size gridSize, int binCount, bool applyInsidePartitioning);
14+
virtual ~HistogramBuilder() { };
15+
16+
cv::Size getGridSize() const { return _gridSize; }
17+
void setGridSize(cv::Size gridSize);
18+
19+
bool isInsidePartitioningApplied() const { return _applyInsidePartitioning; }
20+
void setApplyInsidePartitioning(bool applyInsidePartitioning);
21+
22+
int getBinCount() const { return _binCount; }
23+
void setBinCount(int binCount);
24+
25+
virtual int histogramLength();
26+
virtual cv::Mat build(const cv::Mat &image);
27+
28+
protected:
29+
cv::Mat getGaussianKernel(cv::Size size, double sigma) const;
30+
cv::Mat getRegionHistogram(const cv::Mat &region, int binCount, const cv::Mat &gaussianKernel);
31+
cv::Mat compute(const cv::Mat &image, cv::Size gridSize, int binCount, bool applySlidedGrid);
32+
33+
private:
34+
cv::Size _gridSize;
35+
bool _applyInsidePartitioning;
36+
int _binCount;
37+
};
38+
}
39+
40+
#endif //PALM_HISTOGRAMBUILDER_H

PALM/IlluminationFilter.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include "IlluminationFilter.h"
2+
3+
palm::IlluminationFilter::IlluminationFilter(double alpha, int returnType)
4+
{
5+
setAlpha(alpha);
6+
setReturnType(returnType);
7+
}
8+
9+
void palm::IlluminationFilter::setAlpha(double alpha)
10+
{
11+
CV_Assert(alpha > 0 && alpha < 1);
12+
13+
_alpha = alpha;
14+
}
15+
16+
void palm::IlluminationFilter::setReturnType(int returnType)
17+
{
18+
CV_Assert(returnType == CV_8U || returnType == CV_64F);
19+
20+
_returnType = returnType;
21+
}
22+
23+
cv::Mat palm::IlluminationFilter::apply(const cv::Mat &image)
24+
{
25+
CV_Assert(!image.empty() && image.type() == CV_8UC3);
26+
27+
cv::Mat out = cv::Mat::zeros(image.rows, image.cols, _returnType);
28+
for (int i = 0; i < out.rows; i++)
29+
{
30+
for (int j = 0; j < out.cols; j++)
31+
{
32+
cv::Vec3b value = image.at<cv::Vec3b>(i, j);
33+
double b = value.val[0] / 255.0;
34+
double g = value.val[1] / 255.0;
35+
double r = value.val[2] / 255.0;
36+
37+
double temp = 0.5 + std::log(g) - _alpha * std::log(b) - (1 - _alpha) * std::log(r);
38+
if (temp > 1) temp = 1;
39+
if (temp < 0) temp = 0;
40+
41+
if (_returnType == CV_8U)
42+
{
43+
out.at<uchar>(i, j) = (uchar) (temp * 255.0);
44+
}
45+
else if (_returnType == CV_64F)
46+
{
47+
out.at<double>(i, j) = temp;
48+
}
49+
}
50+
}
51+
52+
return out;
53+
}

PALM/IlluminationFilter.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef PALM_FILTER_H
2+
#define PALM_FILTER_H
3+
4+
#include <opencv2/core.hpp>
5+
6+
7+
namespace palm
8+
{
9+
class IlluminationFilter
10+
{
11+
public:
12+
IlluminationFilter(double alpha = 0.3, int returnType = CV_8U);
13+
virtual ~IlluminationFilter() { }
14+
15+
double getAlpha() { return _alpha; }
16+
void setAlpha(double alpha);
17+
18+
int getReturnType() { return _returnType; }
19+
void setReturnType(int returnType);
20+
21+
cv::Mat apply(const cv::Mat &image);
22+
23+
protected:
24+
25+
private:
26+
double _alpha;
27+
int _returnType;
28+
};
29+
}
30+
31+
#endif //PALM_FILTER_H

0 commit comments

Comments
 (0)