RGB 컬러 이미지의 gray level의 cdf를 이용해서 histogram equalization을 수행한다. 컬러 이미지의 gray level은
$$gray = \frac{r + g+ b}{3}$$
으로 정의한다.
void test_color_equalize_new(CRaster& raster, CRaster& out) {
int hist[256] = {0};
int chist[256], lut[256], partition[256 + 1];
CSize sz = raster.GetSize();
out = raster; // clone;
// pdf of gray level: g = (r + g + b) / 3
for (int y = 0; y < sz.cy; y++) {
BYTE *p = (BYTE *)raster.GetLinePtr(y);
for (int x = 0; x < sz.cx; x++){
int a = *p++; a += *p++; a += *p++;
hist[a / 3]++;
}
};
// cdf;
chist[0] = hist[0];
for (int i = 1; i < 256; i++)
chist[i] = hist[i] + chist[i - 1];
/* assign equal number of pixels in each gray levels;*/
int num_pixels = sz.cx * sz.cy;
double pixels_per_level = double(num_pixels) / 256;
/* first and last in partition */
partition[0] = 0;
partition[256] = 256;
/* intermediate; */
for (int j = 0, i = 1; i < 256; i++) {
double desired = i * pixels_per_level;
while (chist[j + 1] <= desired) j++;
/* nearest interpolation */
if ((desired - chist[j]) < (chist[j + 1] - desired)) partition[i] = j;
else partition[i] = j + 1;
}
/* fill equalization LUT */
for (int j = 0; j < 256; j++) {
int i = 0;
while (partition[i + 1] <= j) i++;
lut[j] = i;
}
// needs hue preserving processes;
for (int y = 0; y < sz.cy; y++) {
BYTE *p = (BYTE *)raster.GetLinePtr(y);
BYTE *q = (BYTE *)out.GetLinePtr(y);
for (int x = 0; x < sz.cx; x++) {
*q++ = lut[*p++]; *q++ = lut[*p++]; *q++ = lut[*p++];
}
}
}
void test_color_equalize_HSV(CRaster& raster, CRaster& out) {
int hist[256] = {0};
int chist[256] = {0}, lut[256] = {0}, partition[256 + 1];
CSize sz = raster.GetSize();
out = raster; // cloning;
std::vector<double> fH(sz.cx * sz.cy);
std::vector<double> fV(sz.cx * sz.cy);
std::vector<double> fS(sz.cx * sz.cy);
int n = sz.cx * sz.cy;
double r, g, b;
for (int y = 0, k = 0; y < sz.cy; y++) {
BYTE *p = (BYTE *)raster.GetLinePtr(y);
for (int x = 0; x < sz.cx; x++, k++){
b = *p++, g = *p++, r = *p++;
RGBtoHSV(r / 255., g / 255., b / 255., fH[k], fS[k], fV[k]);
}
};
// make histogram of V-color;
for (int k = 0; k < n; k++)
hist[int(fV[k] * 255)]++;
// cdf;
chist[0] = hist[0];
for (int i = 1; i < 256; i++) {
chist[i] = hist[i] + chist[i - 1];
}
/* assign equal number of pixels in each V-color;*/
int num_pixels = sz.cx * sz.cy;
double pixels_per_level = double(num_pixels) / 256;
/* first and last in partition */
partition[0] = 0;
partition[256] = 256;
/* intermediate; */
for (int j = 0, i = 1; i < 256; i++) {
double desired = i * pixels_per_level;
while (chist[j + 1] <= desired) j++;
/* nearest interpolation */
if ((desired - chist[j]) < (chist[j + 1] - desired)) partition[i] = j;
else partition[i] = j + 1;
}
/* fill equalization LUT */
for (int j = 0; j < 256; j++) {
int i = 0;
while (partition[i + 1] <= j) i++;
lut[j] = i;
}
for (int k = 0; k < n; k++)
fV[k]= lut[int(fV[k] * 255)] / 255.;
for (int y = 0, k = 0; y < sz.cy; y++) {
BYTE *q = (BYTE *)out.GetLinePtr(y);
for (int x = 0; x < sz.cx; x++, k++) {
HSVtoRGB(fH[k], fS[k], fV[k], r, g, b);
*q++ = int(b * 255);
*q++ = int(g * 255);
*q++ = int(r * 255);
}
}
}
/* fR Red component, range: [0, 1]
** fG Green component, range: [0, 1]
** fB Blue component, range: [0, 1]
** fH Hue component, range: [0, 360]
** fS Hue component, range: [0, 1]
** fV Hue component, range: [0, 1] */
void RGBtoHSV(double fR, double fG, double fB, double& fH, double& fS, double& fV);
void HSVtoRGB(double fH, double fS, double fV, double& fR, double& fG, double& fB);
'Image Recognition > Fundamental' 카테고리의 다른 글
FFT를 이용한 영상의 미분 (0) | 2022.02.12 |
---|---|
SVD Fitting (0) | 2022.02.07 |
Least Squares Fitting of Ellipses (0) | 2022.01.27 |
Circle Fitting: Pratt (0) | 2022.01.20 |
Best-fit Ellipse 2 (0) | 2022.01.18 |