直方图的均衡化和规定化

1.直方图的均衡化
(1)均衡化的原理和达到的目的
直方图的灰度值进行处理,让个数较多的灰度值进行扩展,灰度值较小的进行压缩,让灰度区域和亮度区域展示更明显,提高了对比度,让人的视觉效应更明显。
(2)均衡化实现方法
算出每个灰度级对应的概率,然后使用累机函数,把计算的概率依次累计起来。用累积起来的概率,重新计算新的像素点。如果是灰度图像就只算一个,如果是彩色就要分别计算RGB三种的。
(3)均衡画后图片的对比

2直方图的规定化
1.将原图的灰度直方图改为希望的灰度直方图。
2.自己规定直方图像素的分布,可以使用线性函数,非线性函数,只有满足规定的所有像素值的概率之和为1且连续就满足规定条件。
3计算出原直方图的累计,和规定直方图的累计。然后用原直方图的累计概率依次和规定直方图累计概率比较,当两者的差的绝对值最小时,就将原直方图像素映射到对应规定华图片上去
4 规定后图片和原图对比

3.图片的滤波
1.均值滤波
2.中值滤波
4直方图的部分增强

using namespace cv;
using namespace std;
void equlilbrium(IplImage *picture, double t_r[],double t_g[], double t_b[])//均衡化
{

int height = picture->height;//图片高度
int width = picture->width;//图片宽度
int R[256], G[256], B[256];//记录原始图片的每个像素的个数的数组
int r = 0, g = 0, b = 0;//承载像素的具体值
memset(R, 0, sizeof(R));//初始化
memset(G, 0, sizeof(G));
memset(B, 0, sizeof(B));
for (int i = 0; i < height; i++)//统计直方图像素的个数
{
    for (int j = 0; j < width; j++)
    {
        b = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 0);
        g = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 1);
        r = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 2);
        R[r]++, G[g]++, B[b]++;
    }
}
double R_ratio[256], G_ratio[256], B_ratio[256];
memset(R_ratio, 0, sizeof(R_ratio));
memset(G_ratio, 0, sizeof(G_ratio));
memset(B_ratio, 0, sizeof(B_ratio));
for (int i = 0; i < 256; i++)//每个像素所占的比列
{
    R_ratio[i] = (double)R[i] / (height*width);
    G_ratio[i] = (double)G[i] / (height*width);
    B_ratio[i] = (double)B[i] / (height*width);
}
for (int i = 0; i < 256; i++)//累积函数
{
    if (i == 0)
    {
        t_r[i] = R_ratio[i];
        t_g[i] = R_ratio[i];
        t_b[i] = R_ratio[i];
    }
    else
    {
        t_r[i] = t_r[i - 1] + R_ratio[i];
        t_g[i] = t_g[i - 1] + G_ratio[i];
        t_b[i] = t_b[i - 1] + B_ratio[i];
    }
    B[i] = (int)255 * t_b[i] + 0.5;//求出均衡化后的新的像素点
    G[i] = (int)255 * t_g[i] + 0.5;
    R[i] = (int)255 * t_r[i] + 0.5;
}
for (int i = 0; i < height; i++)//将新的像素点赋值在原图片上
{
    for (int j = 0; j < width; j++)
    {
        b = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 0);
        g = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 1);
        r = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 2);
        CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 0) = B[b];
        CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 1) = G[g];
        CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 2) = R[r];

    }
}

}

void stipulate(IplImage *picture, double t_r[], double t_g[], double t_b[])//规定化
{
double stipulate_r[256], stipulate_g[256], stipulate_b[256];
int sum = 0;
for (int i = 0; i < 256; i++)//构造规定函数
{
sum = sum + 2 * i;
}
for (int i = 0; i < 512; i = i + 2)
{
stipulate_r[i / 2] = i*1.0 / sum;
stipulate_g[i / 2] = i*1.0 / sum;
stipulate_b[i / 2] = i*1.0 / sum;
}
/* int sum = 0;
for (int i = 0; i < 256; i++)
{
sum = sum + i;
}
for (int i = 0; i < 256; i++)
{
stipulate_r[i] = i *1.0/ sum;
stipulate_g[i] = i *1.0/ sum;
stipulate_b[i] = i *1.0/ sum;
}*/
for (int i = 1; i < 256; i++)//累计函数
{
stipulate_r[i] += stipulate_r[i - 1];
stipulate_g[i] += stipulate_g[i - 1];
stipulate_b[i] += stipulate_b[i - 1];
}
double stipulate1_r[256], stipulate1_g[256], stipulate1_b[256];
memset(stipulate1_r, 0, sizeof(stipulate1_r));
memset(stipulate1_b, 0, sizeof(stipulate1_b));
memset(stipulate1_g, 0, sizeof(stipulate1_g));

for (int i = 0; i height; i++)
{
    for (int j = 0; j < picture->width; j++)
    {

        int b = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 0);
        int g = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 1);
        int r = CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 2);
        double min_r = 1, min_g = 1, min_b = 1;
        int count_r = 0, count_g = 0, count_b = 0;
        for (int k = 0; k < 256; k++)//寻找最小值映射
        {
            if (min_r > fabs(stipulate_r[k] - t_r[r]))
            {

                min_r = fabs(stipulate_r[k] - t_r[r]);
                count_r = k;
            }
            if (min_g > fabs(stipulate_g[k] - t_g[g]))
            {
                min_g = fabs(stipulate_g[k] - t_g[g]);
                count_g = k;
            }
            if (min_b > fabs(stipulate_b[k] - t_b[b]))
            {
                min_b = fabs(stipulate_b[k] - t_b[b]);
                count_b = k;
            }
        }
        CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 0) = count_b;
        CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 1) = count_g;
        CV_IMAGE_ELEM(picture, uchar, i, j * 3 + 2) = count_r;

    }
}

}

void joint(IplImage *blk,IplImage *pic,int x,int y ) //图片拼接技术
{
if (blk != NULL&&pic!= NULL)
{
for (int i = 0; i < pic->height; i++)
{
for (int j = 0; j < pic->width; j++)
{
CV_IMAGE_ELEM(blk, uchar, y + i, (j + x) * 3) = CV_IMAGE_ELEM(pic, uchar, i, j * 3);//i行j列;
CV_IMAGE_ELEM(blk, uchar, y + i, (j + x) * 3 + 1) = CV_IMAGE_ELEM(pic, uchar, i, j * 3 + 1);
CV_IMAGE_ELEM(blk, uchar, y + i, (j + x) * 3 + 2) = CV_IMAGE_ELEM(pic, uchar, i, j * 3 + 2);
}
}
}
}

int main()
{
IplImage * picture,*pdest=NULL,*Blkpic=NULL;
picture = cvLoadImage(“D:/2000.jpg”);//载入图片
pdest = cvCreateImage(cvSize(picture->width/2, picture->height/2),picture->depth, picture->nChannels);
Blkpic = cvCreateImage(cvSize(picture->width, picture->height), picture->depth, picture->nChannels);
cvResize(picture, pdest);
joint(Blkpic, pdest, 0, 0);
//cvNamedWindow(“pro”,2);//创建窗口
//cvShowImage(“pro”,pdest);//展示图片
double t_r[256], t_g[256], t_b[256];
memset(t_r, 0, sizeof(t_r));
memset(t_g, 0, sizeof(t_g));
memset(t_b, 0, sizeof(t_b));
equlilbrium(pdest, t_r, t_g, t_b);
joint(Blkpic, pdest, picture->width / 2, 0);
stipulate(pdest, t_r, t_g, t_b);
joint(Blkpic, pdest, 0, picture->height / 2);
cvNamedWindow(“src”);
cvMoveWindow(“src”, 0, 0);
cvShowImage(“src”, Blkpic);
cvWaitKey(0);
cvReleaseImage(&pdest);//摧毁图片
cvReleaseImage(&picture);
cvReleaseImage(&Blkpic);
cvDestroyWindow(“src”);//释放窗口
return 0;
}

你可能感兴趣的:(图像处理)