图像的对数变换和伽马变换

图像的对数变换和伽马变换是两种常用的图像增强技术,用于改善图像的亮度和对比度。
对数变换,也称为对数压缩,通过将图像中的像素值取对数来改变像素的亮度。对数变换公式如下:
g(x, y) = c * log(1 + f(x, y))
其中,g(x, y) 是变换后的像素值,f(x, y) 是原始像素值,c 是一个常数,用于控制对比度的增益。对数变换可以扩展低亮度区域,压缩高亮度区域,从而提高图像的可视化效果。
伽马变换,也称为幂律变换,通过对图像进行幂次运算来调整像素的亮度。伽马变换公式如下:
g(x, y) = c * [f(x, y)]^γ
其中,g(x, y) 是变换后的像素值,f(x, y) 是原始像素值,c 是一个常数,用于控制对比度的增益,γ 是一个参数,称为伽马值,用于调整亮度的曲线形状。当 γ 大于 1 时,增加了高灰度级之间的对比度;当 γ 小于 1 时,增加了低灰度级之间的对比度。

通过调整对数变换和伽马变换中的参数,可以根据不同图像的特点和需求,实现对图像亮度和对比度的灵活控制。这些变换技术在数字图像处理中被广泛应用于图像增强、显示和校正等领域。
对数变换的曲线:
对数曲线是一个单调递增的函数
对图像的对数变换
对空域的对数变换,是指对原图的逐像素实现对数变换的映射,可以看到在像素值较暗的地方,曲线斜率较大,在像素值较亮的地方,曲线斜率比较小;因此,对数变换可以扩展低亮度区域,压缩高亮度区域,从而提高图像的可视化效果。
原图:
对数变换图:
可以看到树林阴影部分明显对比度更加清晰了,但是亮区整体变多了。
伽马变换:
图像的伽马变换(Gamma Transformation)是一种常用的非线性灰度变换方法,可以调整图像的对比度。它基于光照强度与人眼感知之间的非线性关系。伽马变换的一般公式如下:
g(x, y) = c * f(x, y)^γ
其中,f(x, y)表示输入图像的像素值,g(x, y)表示输出图像的像素值,c是常数,γ是调节参数。γ决定了变换的形状,较小的γ值会使得图像变亮,较大的γ值会使得图像变暗。
γ=1时,就是图中的恒等变换;γ>1时,扩增暗区的对比度;γ<1时,扩增亮区对比度
γ=1.5:
γ=0.5:
C++代码:
#include<opencv2/core.hpp>
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;


void Spatial_Log_Trans(Mat src ,Mat &des,float lamda)
{
    //为des开辟空间
    cout << "图像的尺寸为(" << src.rows << "," << src.cols << ")" << endl;
    des.create(src.rows,src.cols, CV_8UC1);
    //进行空域的对数变换
    for (int r=0;r<src.rows;r++)
    {
        for (int c=0;c<src.cols;c++)
        {
            //对数计算公式: g(x, y) = c * log(1 + f(x, y))
            int gray=saturate_cast<uchar>(int(lamda *log(1 + src.at<uchar>(r, c))));
            des.at<uchar>(r, c) = gray;
            //cout << gray << endl;
        }
    }
}

void draw_log_curve()
{
    const int width = 800;
    const int height = 600;

    Mat curve(height, width, CV_8UC3, Scalar(255, 255, 255));

    // 定义放大系数
    double c = 30;

    for (int x = 0; x < width; x++)
    {
        // 计算对数变换
        int y = static_cast<int>(c * std::log(1 + x));
        Point pt(x, height - y);

        // 绘制曲线点
        circle(curve, pt, 1, Scalar(0, 0, 0), FILLED);
    }

    imshow("Log Transformation Curve", curve);
}
void Gamma_Trans(const Mat src,Mat &des,float alpha,float gama) 
{
    //为des开辟空间
    des.create(src.rows,src.cols,CV_8UC1);
    for (int r=0;r<src.rows;r++)
    {
        for (int c=0;c<src.cols;c++)
        {
            //gama变换的公式: g(x, y) = c * f(x, y)^γ
            int gray = saturate_cast<uchar>(int(alpha * pow(src.at<uchar>(r, c), gama)));
            des.at<uchar>(r, c) = gray;
        }
    }
}
int main(int argc,char *argv)
{
    Mat src = imread("dark.jpg");          //读图
    cvtColor(src,src,CV_BGR2GRAY);//灰度变换
    PrintMs();
    Mat slr,Gamma;
    Spatial_Log_Trans(src, slr,30);
    float r = 1, ga = 0.8;
    Gamma_Trans(src,Gamma, r,ga);
    PrintMs("myExchange");
    namedWindow("src");
    imshow("src", src);
    namedWindow("空域的对数变换");
    imshow("空域的对数变换", slr);
    namedWindow("gama变换");
    imshow("gama变换",Gamma);
    draw_log_curve();
    waitKey(0);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值