这次主要针对真彩色图像做的增强,将RGB域转为HSI域,增强I分量,达到增强效果,效果如下:
原始图像
增强后图像
代码如下:

#define MIN(a, b) ((a) < (b) ? (a) : (b))    
#define MAX(a, b) ((a) > (b) ? (a) : (b))    
#define EPS 1e-16 

/// 彩色空间转换
bool RGB2HSI(uchar *imgIn, int nchannels, double *Hvector, double *Svector, double *Ivector, int width, int height)
{
    if (imgIn == NULL || nchannels != 3)
    {
        return false;
    }
    int index = 0;
    for (int i = 0; i < width * height * nchannels; i = i + 3)
    {
        double b = imgIn[i + 0] / 255.0;
        double g = imgIn[i + 1] / 255.0;
        double r = imgIn[i + 2] / 255.0;
        double num = 0.5 * (r - g + r - b);
        double den = sqrt((r - g) * (r - g) + (r - b) * (g - b));
        double theta = acos(num / (den + EPS));
        double hh = theta;
        if (b > g)
        {
            hh = 2 * PI - hh;
        }
        hh /= 2 * PI;
        num = MIN(MIN(r, g), b);
        den = r + g + b;
        double ss = 1 - 3 * num / (den + EPS);
        if (ss == 0)
        {
            hh = 0;
        }
        double ii = (r + g + b) / 3;
        Hvector[index] = hh;
        Svector[index] = ss;
        Ivector[index++] = ii;
    }

    return true;
}

bool HSI2RGB(double *Hvector, double *Svector, double *Ivector, uchar *imgOut, int width, int height)
{
    if (Hvector == NULL || Svector == NULL || Ivector == NULL)
    {
        return false;
    }
    int index = 0;
    for (int i = 0; i < height * width; i++)
    {
        double hh = Hvector[i] * 2 * PI;
        double ss = Svector[i];
        double ii = Ivector[i];
        double B, G, R;
        if (hh >= 0 && hh < 2 * PI / 3)
        { 
            B = ii * (1 - ss);
            R = ii * (1 + ss * cos(hh) / cos(PI / 3 - hh));
            G = 3 * ii - R - B;
        }
        else if (hh >= 2 * PI / 3 && hh < 4 * PI / 3)
        {
            R = ii * (1 - ss);
            G = ii * (1 + ss * cos(hh - 2 * PI / 3) / cos(PI - hh));
            B = 3 * ii - R - G;
        }
        else if (hh >= 4 * PI / 3 && hh <= 2 * PI)
        {
            G = ii * (1 - ss);
            B = ii * (1 + ss * cos(hh - 4 * PI / 3) / cos(5 * PI / 3 - hh));
            R = 3 * ii - G - B;
        }
        R = MAX(0, MIN(1, R));
        G = MAX(0, MIN(1, G));
        B = MAX(0, MIN(1, B));

        imgOut[index++] = uchar(B * 255);
        imgOut[index++] = uchar(G * 255);
        imgOut[index++] = uchar(R * 255);
    }
    return true;
}

/// 对比度增强
bool ImAdjust(uchar *imgIn, uchar *imgOut, int width, int height, int nchannels, 
              double low_in, double high_in, double low_out, double high_out, double gamma)
{
    if (imgIn == NULL || !(nchannels == 1 || nchannels == 3) || low_in < 0 || low_in > 1 ||
        high_in < low_in || high_in > 1 || low_out < 0 || low_out > 1 || high_out < low_out || high_out > 1)
    {
        return false;
    }

    if ( nchannels == 1)
    {
        for (int i = 0; i < height * width; i++)
        {
            if (imgIn[i] < low_in * 255)
            {
                imgOut[i] = uchar(low_out * 255);
            }
            else if (imgIn[i] > high_in * 255)
            {
                imgOut[i] = uchar(high_out * 255);
            }
            else
            {
                double temp = pow((double(imgIn[i]) - low_in * 255) / (255 *(high_in - low_in)), gamma) *
                    (high_out - low_out) * 255 + low_out * 255; 
                imgOut[i] = uchar(temp);
            }
        }
    }
    else if (nchannels == 3)
    {
        double *Hvector = new double[width * height];
        double *Svector = new double[width * height];
        double *Ivector = new double[width * height];

        if (!RGB2HSI(imgIn, nchannels, Hvector, Svector, Ivector, width, height))
        {
            delete[] Hvector;
            delete[] Svector;
            delete[] Ivector;
            return false;
        }
        // enhancement the I vector
        for (int i = 0; i < width * height; i++)
        {
            if (Ivector[i] < low_in)
            {
                Ivector[i] = low_out;
            }
            else if (Ivector[i] > high_in)
            {
                Ivector[i] = high_out;
            }
            else
            {
                double temp = pow((Ivector[i] - low_in) / (high_in - low_in), gamma) *
                    (high_out - low_out) + low_out; 
                if (temp < low_out)
                {
                    temp = low_out;
                }
                if (temp > high_out)
                {
                    temp = high_out;
                }
                Ivector[i] = temp;
            }
        }

        HSI2RGB(Hvector, Svector, Ivector, imgOut, width, height);

        delete[] Hvector;
        delete[] Svector;
        delete[] Ivector;
    }



    return true;
}