图片的直方图均衡化

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

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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值