欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图片的直方图均衡化

程序员文章站 2022-04-30 13:52:40
...

功能,实现图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
图片的直方图均衡化
左上为原图灰度化,右上为原图的直方图
左下为均衡化后的图,右下为均衡化后的直方图
总结:感觉聊过不怎么样。。。

int main()
{
	int *arr = new int[256]();
	Mat image = imread("D:/Code/C++/Practice/Pronucination/test/123.jpg");
	Mat shuzu1,shuzu2;
	cout << image.channels() << endl;
	cout << "row = " << image.rows << ";col = " << image.cols << endl;
	image = gray_image(image);
	Histogram_array(image, arr);
	shuzu1 = drawHist(image, arr);
	Mat image2 = Equalization(image, arr);
	Histogram_array(image2, arr);
	shuzu2 = drawHist(image2, arr);
	Mat img = Merge_image(image, shuzu1, image2, shuzu2);
	img = Change_Size(img, 540, 960);
	imshow("图像", img);
	waitKey();
	return 0;
}
//输入灰度图原图像
    //输出一个直方图数组
    void Histogram_array(Mat img,int* pixel_value)
    {
        int i, j;
        uchar* data; 
        int value1; 
        //int *pixel_value = new int[256]();
        if (img.channels() == 1)
        {
            for (i = 0; i < img.rows; ++i)
            {
                data = img.ptr<uchar>(i);
                for (j = 0; j < img.cols; ++j)
                {
                    value1 = data[j];
                    pixel_value[value1]++;//记录每个像素值的个数
                }
            }
        }
    }
//输入:一张图片,主要是获取图像的行列
    //输出:一个直方图
    Mat drawHist(Mat img,int *arr) 
    {
        int i,j,k;
        int value = 0;
        uchar* data;
        int row = img.rows,col = img.cols;
        Mat picture(row, col, CV_8UC1); // 新建画布
        int MaxCount = Max_Number(arr,256);//寻找在处于某一灰度级中个数最多的像素个数
        double yscaleRate = double(row) / MaxCount;//y缩放比例
        double xscaleRate = col / 256;//x缩放比例
        int yAxis[256];
        for (int i = 0; i < 256; i++) 
            yAxis[i] = int(arr[i] * yscaleRate);
        //绘制直方图
        for (i = 0; i < picture.rows; ++i)
        {
            data = picture.ptr<uchar>(i);
            for (j = 0; j < 256; ++j)
            {
                if (yAxis[j] > 0)
                {
                    for (k = 0; k < xscaleRate; ++k)
                    {
                        value = value = j * xscaleRate + k;
                        data[value] = 255;
                    }
                    yAxis[j]--;
                }
                else
                {
                    for (k = 0; k < xscaleRate; ++k)
                    {
                        value = value = j * xscaleRate + k;
                        data[value] = 0;
                    }
                }
            }
        }
        return picture;
    }
//直方图均衡化
    //输入:原图像,直方图数组
    //输出:均衡化后的图像
    Mat Equalization(Mat img, int* arr)
    {
        int row = img.rows;
        int col = img.cols;
        int i,j,sum = 0;
        int t1 = 0, t2 = 0;
        float error1 = 0, error2 = 0;
        int t = 0;
        uchar* data;
        float *ret = new float[256]();
        //计算概率并累计概率
        for (i = 0; i < 256; ++i)
        {
            if (arr[i] > 0)
                sum++;
            ret[i] = (arr[i] * 1.0) / (row * col * 1.0);
            if (i == 0)
                continue;
            else
                ret[i] = ret[i] + ret[i - 1];
        }
        //乘上灰度个数
        for (i = 0; i < 256; ++i)
        {
            t1 = (int)(ret[i] * sum);//下取整
            t2 = t1+1;//上取整
            error1 = ret[i] * sum - t1;
            error2 = t2 - ret[i] * sum;
            if (error1 > error2)
                ret[i] = t2;
            else
                ret[i] = t1;
        }
        //更改原图像
        for (i = 0; i < row; ++i)
        {
            data = img.ptr<uchar>(i);
            for (j = 0; j < col; ++j)
            {
                t = data[j];
                t = ret[t];
                data[j] = t;
            }
        }
        return img;
    }
//输入各个尺寸的图像
    //输出,将4个图像拼接起来
    Mat Merge_image(Mat img, Mat img1, Mat img2, Mat img3)
    {
        int row = img.rows, col = img.cols;
        Mat result(row, col, CV_8UC1);
        //改变每个图片的尺寸
        img  = Change_Size(img,  row / 2, col / 2);
        img1 = Change_Size(img1, row / 2, col / 2);
        img2 = Change_Size(img2, row / 2, col / 2);
        img3 = Change_Size(img3, row / 2, col / 2);
        //把每个改变尺寸后的图像拼接起来
        int i, j;
        int t = 0;
        uchar* ret;
        uchar* data, * data1, * data2, * data3;
        for (i = 0; i < row; ++i)
        {
            ret = result.ptr<uchar>(i);
            for(j = 0;j < col; ++j)
            { 
                //上
                if(i < row/2)
                {
                    //左
                    if (j < col/2)
                    {
                        data = img.ptr<uchar>(i);
                        ret[j] = data[j];
                    }
                    //右
                    else
                    { 
                        data1 = img1.ptr<uchar>(i);
                        ret[j] = data1[j - col/2];
                    }
                }
                //下
                else
                {
                    t = i - row/2;
                    //左
                    if (j < col / 2)
                    {
                        data2 = img2.ptr<uchar>(t);
                        ret[j] = data2[j];
                    }
                    //右
                    else
                    {
                        data3 = img3.ptr<uchar>(t);
                        ret[j] = data3[j - col/2];
                    }
                }
            }
        }
        return result;
    }

参考博客:https://blog.csdn.net/schwein_van/article/details/84336633

相关标签: 图像处理