C++数字图像处理(1)-伽马变换

1、算法原理

    伽马变换(幂律变换)是常用的灰度变换,是一种简单的图像增强算法。数学公式如下:

(1)

    式(1)中,r为输入的灰度值,取值范围为[0, 1]。C称为灰度缩放系数,用于整体拉伸图像灰度,通常取值为1。gamma取值灰度输入输出曲线图如下:

图(1) gamma曲线图

    从图(1)可知:当gamma>1.0时,伽马变换将拉低图像灰度值,图像视觉上变暗;当gamm<1.0时,伽马变换将提高图像的灰度值,图像视觉上变亮。

2、算法定义

    输入:8位灰度图像。

    输出:8位灰度图像。

    参数:gamma值、C值。

3、算法实现

(1)、公式实现

//函数名:gammaTransformation
//作用:实现灰度变换中的伽马变换
//参数:
//matInput:输入图像
//matOutput : 输出图像
//fGamma : 伽马值
//fC : C值(缩放系数)
//返回值:无
//注:支持单通道8位灰度图像
void gammaTransformation(cv::Mat& matInput, cv::Mat& matOutput, float fGamma, float fC /*= 1.0f*/)
{
	assert(matInput.elemSize() == 1);
	//构造输出图像
	matOutput = cv::Mat::zeros(matInput.rows, matInput.cols, matInput.type());

	//循环中尽量避免除法
	float fNormalFactor = 1.0f / 255.0f;
	for (size_t r = 0; r < matInput.rows; r++)
	{
		unsigned char* pInput = matInput.data + r * matInput.step[0];
		unsigned char* pOutput = matOutput.data + r * matOutput.step[0];
		for (size_t c = 0; c < matInput.cols; c++)
		{
			//gamma变换
			float fOutput = std::pow(pInput[c] * fNormalFactor, fGamma) * fC;
			//数值溢出判断
			fOutput = fOutput > 1.0f ? 1.0f : fOutput;
			//输出
			pOutput[c] = static_cast<unsigned char>(fOutput * 255.0f);
		}
	}
}

(2)、查表加速

    几乎所有的灰度变换算法中,都可以使用查表方法进行加速。在【公式实现】中,循环中调用了库函数pow、并进行了一次if判断。这些操作,可以在循环外提提前计算好,循环中查表即可。在嵌入式系统中,查表法使用较多。优化后的代码如下:

void gammaTransformation(cv::Mat& matInput, cv::Mat& matOutput, float fGamma, float fC /*= 1.0f*/)
{
	assert(matInput.elemSize() == 1);
	//构造输出图像
	matOutput = cv::Mat::zeros(matInput.rows, matInput.cols, matInput.type());

	//循环中尽量避免除法
	float fNormalFactor = 1.0f / 255.0f;
	//构造查询表
	std::vector<unsigned char> lookUp(256);
	for (size_t m = 0; m < lookUp.size(); m++)
	{
		//gamma变换
		float fOutput = std::pow(m * fNormalFactor, fGamma) * fC;
		//数值溢出判断
		fOutput = fOutput > 1.0f ? 1.0f : fOutput;
		//输出
		lookUp[m] = static_cast<unsigned char>(fOutput * 255.0f);
	}

	for (size_t r = 0; r < matInput.rows; r++)
	{
		unsigned char* pInput = matInput.data + r * matInput.step[0];
		unsigned char* pOutput = matOutput.data + r * matOutput.step[0];
		for (size_t c = 0; c < matInput.cols; c++)
		{
			//查表gamma变换
			pOutput[c] = lookUp[pInput[c]];
		}
	}
}

 

(3)、测试结果

 

技术交流合作QQ:3355138068

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值