图像处理:直方图均衡化

下面是一个例子

这样就可以直观的看到直方图的变换了,可以理解为一个非线性的分段的平移拉伸 

/*
* 画数组直方图,画在一个Mat上
*/
void show_lzb(int arr[], int size, string title)
{
    Mat drawImage = Mat::zeros(Size(256, 256), CV_8UC3);

    int _max = 0;
    for (int i = 0; i < size; i++)
    {
        if (arr[i] > _max)
        {
            _max = arr[i];//找到数组中的最大值,后面需要归一化
        }
    }

    for (int i = 0; i < 256; i++)
    {
        int current_value = (int)(double(arr[i]) / double(_max) * 256);//每次都要将数组的值根据最大值归一化到0-255之间
        line(drawImage, Point(i, drawImage.rows - 1), Point(i, drawImage.rows - 1 - current_value), Scalar(255, 0, 255));
    }
    imshow(title, drawImage);
}

void show_lzb(double arr[], int size, string title)
{
    Mat drawImage = Mat::zeros(Size(256, 256), CV_8UC3);

    double _max = 0;
    for (int i = 0; i < size; i++)
    {
        if (arr[i] > _max)
        {
            _max = arr[i];//找到数组中的最大值,后面需要归一化
        }
    }

    for (int i = 0; i < 256; i++)
    {
        int current_value = (int)(double(arr[i]) / double(_max) * 256);//每次都要将数组的值根据最大值归一化到0-255之间
        line(drawImage, Point(i, drawImage.rows - 1), Point(i, drawImage.rows - 1 - current_value), Scalar(255, 0, 255));
    }
    imshow(title, drawImage);
}

/*
* 均衡化JHH
*/
void JHH(Mat& img)
{
    Mat dst = img.clone();
    int row = img.rows;
    int col = img.cols;
    int N = row * col;
    //计算直方图
    int arr_1[256] = { 0 };
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            uchar value = img.at<uchar>(i, j);
            arr_1[value]++;
        }
    }
    show_lzb(arr_1, 256, "arr_1");
    //计算概率
    double arr_2[256] = { 0 };
    for (int i = 0; i < 256; i++)
    {
        arr_2[i] = (double)arr_1[i] / N;
    }
    show_lzb(arr_2, 256, "arr_2");
    //计算概率密度
    double arr_3[256] = { 0 };
    arr_3[0] = arr_2[0];
    for (int i = 1; i < 256; i++)
    {
        arr_3[i] = arr_3[i - 1] + arr_2[i];
    }
    show_lzb(arr_3, 256, "arr_3");
    //概率密度归一化到255
    int arr_4[256] = { 0 };
    for (int i = 0; i < 256; i++)
    {
        arr_4[i] = (int)(arr_3[i] * 255);
    }
    show_lzb(arr_4, 256, "arr_4");
    //灰度变换
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            uchar value = dst.at<uchar>(i, j);
            dst.at<uchar>(i, j) = arr_4[value];
        }
    }
    imshow("dst", dst);
}

int main()
{
    Mat src = imread("123.jpg", 0);
    imshow("src", src);
    JHH(src);
    waitKey(0);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值