-
Notifications
You must be signed in to change notification settings - Fork 0
/
colorhistogram.cpp
138 lines (114 loc) · 3.51 KB
/
colorhistogram.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "colorhistogram.h"
ColorHistogram::ColorHistogram()
{
histSize[0] = histSize[1] = histSize[2] = 256;
hranges[0] = 0.0;
hranges[1] = 255.0;
ranges[0] = hranges;
ranges[1] = hranges;
ranges[2] = hranges;
channels[0] = 0;
channels[1] = 1;
channels[2] = 2;
}
Mat ColorHistogram::getHistogram(const Mat &image)
{
MatND hist;
hranges[0] = 0.0;
hranges[1] = 255.0;
channels[0] = 0;
channels[1] = 1;
channels[2] = 2;
calcHist(&image,
1,
channels,
Mat(),
hist,
3,
histSize,
ranges);
return hist;
}
cv::SparseMat ColorHistogram::getSparseHistogram(const cv::Mat &image) {
cv::SparseMat hist(3,histSize,CV_32F);
// BGR color histogram
hranges[0]= 0.0; // BRG range
hranges[1]= 255.0;
channels[0]= 0; // the three channels
channels[1]= 1;
channels[2]= 2;
// Compute histogram
cv::calcHist(&image,
1, // histogram of 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
3, // it is a 3D histogram
histSize, // number of bins
ranges // pixel value range
);
return hist;
}
// Computes the 2D ab histogram.
// BGR source image is converted to Lab
cv::MatND ColorHistogram::getabHistogram(const cv::Mat &image) {
cv::MatND hist;
// Convert to Lab color space
cv::Mat lab;
cv::cvtColor(image, lab, CV_BGR2Lab);
// Prepare arguments for a 2D color histogram
hranges[0]= -128.0;
hranges[1]= 127.0;
channels[0]= 1; // the two channels used are ab
channels[1]= 2;
// Compute histogram
cv::calcHist(&lab,
1, // histogram of 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
2, // it is a 2D histogram
histSize, // number of bins
ranges // pixel value range
);
return hist;
}
// Computes the 1D Hue histogram with a mask.
// BGR source image is converted to HSV
cv::MatND ColorHistogram::getHueHistogram(const cv::Mat &image) {
cv::MatND hist;
// Convert to Lab color space
cv::Mat hue;
cv::cvtColor(image, hue, CV_BGR2HSV);
// Prepare arguments for a 1D hue histogram
hranges[0]= 0.0;
hranges[1]= 180.0;
channels[0]= 0; // the hue channel
// Compute histogram
cv::calcHist(&hue,
1, // histogram of 1 image only
channels, // the channel used
cv::Mat(), // no mask is used
hist, // the resulting histogram
1, // it is a 1D histogram
histSize, // number of bins
ranges // pixel value range
);
return hist;
}
cv::Mat ColorHistogram::colorReduce(const cv::Mat &image, int div) {
int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
// mask used to round the pixel value
uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
cv::Mat_<cv::Vec3b>::const_iterator it= image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>();
// Set output image (always 1-channel)
cv::Mat result(image.rows,image.cols,image.type());
cv::Mat_<cv::Vec3b>::iterator itr= result.begin<cv::Vec3b>();
for ( ; it!= itend; ++it, ++itr) {
(*itr)[0]= ((*it)[0]&mask) + div/2;
(*itr)[1]= ((*it)[1]&mask) + div/2;
(*itr)[2]= ((*it)[2]&mask) + div/2;
}
return result;
}