-
Notifications
You must be signed in to change notification settings - Fork 2
/
opencv-clahe.cpp
109 lines (86 loc) · 3.29 KB
/
opencv-clahe.cpp
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
/*
* file: opencv-clahe.cpp
* purpose: Small application which takes an input image and applies OpenCV's
* histogram equalization implementation to the image.
*/
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "plotting.hpp"
#include "utility.hpp"
#include <iostream>
#include <chrono>
/*
* Calculates the entropy measurement of a grayscale image.
*/
float calculateEntropy(cv::Mat const & image);
int main(int argc, char ** argv)
{
std::string inputImageFilename;
if (argc >= 2)
{
inputImageFilename = argv[1];
}
else
{
return 2;
}
auto image = cv::imread(inputImageFilename, cv::IMREAD_GRAYSCALE);
if (image.empty())
{
std::cout << "Unable to open the image: " << inputImageFilename << std::endl;
return 1;
}
// find the histogram of the original image
ImageHistogram grayHistogram;
generateGrayscaleHistogram(image, grayHistogram);
cv::Mat histogramImage;
createHistogramPlot(grayHistogram, 512, 512, histogramImage);
// do normal OpenCV histogram equalization
cv::Mat normalEqualization;
cv::equalizeHist(image, normalEqualization);
// generate CLAHEd image
cv::Mat claheImage;
auto start = std::chrono::high_resolution_clock::now();
auto clahe = cv::createCLAHE();
clahe->apply(image, claheImage);
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
std::cout << "Duration (us): " << duration.count() << std::endl;
// find the histogram of the CLAHE image
ImageHistogram claheHistogram;
generateGrayscaleHistogram(claheImage, claheHistogram);
cv::Mat claheHistImage;
createHistogramPlot(claheHistogram, 512, 512, claheHistImage);
std::cout << "Entropies:" << std::endl;
std::cout << "Original: " << calculateEntropy(image) << std::endl;
std::cout << "OpenCV CLAHE: " << calculateEntropy(claheImage) << std::endl;
std::cout << "OpenCV Normal histeq: " << calculateEntropy(normalEqualization) << std::endl;
std::string const windowNameOriginalImage("Original Image");
std::string const windowNameNewImage("Histogram Equalized Image");
std::string const windowNameOriginalHistogram("Histogram of Original Image");
std::string const windowNameNewHistogram("Histogram of CLAHE Image");
cv::namedWindow(windowNameOriginalImage, cv::WINDOW_NORMAL);
cv::namedWindow(windowNameNewImage, cv::WINDOW_NORMAL);
cv::namedWindow(windowNameOriginalHistogram, cv::WINDOW_NORMAL);
cv::namedWindow(windowNameNewHistogram, cv::WINDOW_NORMAL);
cv::imshow(windowNameOriginalImage, image);
cv::imshow(windowNameNewImage, claheImage);
cv::imshow(windowNameOriginalHistogram, histogramImage);
cv::imshow(windowNameNewHistogram, claheHistImage);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
float calculateEntropy(cv::Mat const & image)
{
ImageHistogram temp;
generateGrayscaleHistogram(image, temp);
auto totalPixels(image.rows * image.cols);
float entropy = 0.0;
for (auto i = 0u; i < 256; ++i)
{
float proportion = static_cast<float>(temp[i]) / totalPixels;
entropy += -1 * proportion * log2(proportion);
}
return isnan(entropy) ? 0.f : entropy;
}