RGB 컬러 이미지의 gray level의 cdf를 이용해서 histogram equalization을 수행한다. 컬러 이미지의 gray level은 

$$gray = \frac{r + g+ b}{3}$$

으로 정의한다.

gray level에 기반한 equalization 결과;
각 color 채널 equalization 결과:
RGB color를 HSV color로 변환한 후 V에 대해서 equalization을 했을 때 결과:

std::vector<BYTE> color_equalize_new(std::vector<BYTE> &rgb) {
    int hist[256] = {0};
    int chist[256], lut[256], partition[256 + 1];
    std::vector<BYTE> out = raster; // clone; 
    // pdf of gray level: g = (r + g + b) / 3
    for (int k = 0; k < rgb.size(); k += 3) {
        int a = rgb[k+0]; a += rgb[k+1]; a += rgb[k+2];
        ++hist[a/3];
    };
    // cdf;
    for (int i = 0, s = 0; i < 256; i++) {
        s += hist[i]; chist[i] = s;
    }
    
    /* assign equal number of pixels in each gray levels;*/
    int num_pixels = rgb.size()/3;
    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++;
        /* chist[j] <= desired < chist[j+1];*/
        /* nearest interpolation */
        if ((desired - chist[j]) < (chist[j+1] - desired)) partition[i] = j;
        else partition[i] = j + 1;
    } 
    /* Find i s.t. partion[i] <= j < partition[i+1];*/
    for (int j = 0; j < 256; j++) {
        int i = 0;
        while (partition[i+1] <= j) i++;
        lut[j] = i;
    } 
    // needs hue preserving processes;
    for (k = rgb.size(); k-->0;)
        res[k] = lut[src[k]];
    return out;
}
std::vector<BYTE> color_equalize_HSV(std::vector<BYTE> &rgb) {
    int hist[256] = {0};
    int chist[256] = {0}, lut[256] = {0}, partition[256 + 1];
    std::vector<BYTE> out = raster; // cloning;
    std::vector<double> fH(rgb.size()/3);
    std::vector<double> fV(rgb.size()/3);
    std::vector<double> fS(rgb.size()/3);

    const int n = rgb.size()/3;
    double r, g, b;
    for (int k = 0; k < rgb.size(); k += 3) {
        b = rgb[k+0], g = rgb[k+1], r = rgb[k+2];
        RGBtoHSV(r / 255, g / 255, b / 255, fH[k], fS[k], fV[k]);
    };	
    // make histogram of V-color;
    for (int k = n; k-->0;)
        ++hist[int(fV[k] * 255)];

    // cdf;
    for (int i = 0, s = 0; i < 256; i++) {
        s += hist[i]; chist[i] = s;
    }
    /* assign equal number of pixels in each V-color;*/
    int num_pixels = rgb.size()/3;
    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 = n; k-->0;)
        fV[k]= lut[int(fV[k] * 255)] / 255.;

    for (int k = 0; k < rgb.size(); k += 3) {
        HSVtoRGB(fH[k], fS[k], fV[k], r, g, b);
        out[k+0] = int(b * 255); 
        out[k+1] = int(g * 255);
        out[k+2] = int(r * 255);
    }
    return out;
}
/* 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);
728x90

'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
Posted by helloktk
,