分段线性拉伸
一、目的与原理
(1)目的:图像增强,增加对比度,为了突出感兴趣的目标或灰度区间,相对抑制那些不感兴趣的灰度区间。常用是三段线性变换,即对一个灰度区间进行线性拉伸,其他的区间被压缩。
(2)原理:本文介绍的是三段线性拉伸,通过设置两个点将线段划分为三段,当k=1的时候,图像没变化,当k<1的时候,图像灰度被抑制,灰度值变小,效果是变得更暗;当k>1的是偶,图像灰度变量,可以通过调节两个点的数据增加图像的对比度。
三段线段的斜率:
① k1 = Y1/X1;
② k2 = (Y2-Y1)/(X2-X1);
③ k3 = (255-Y2)/(255-X2);
三段线段的函数,代入(x,y)和k可求得b1,b2,b3:
二、步骤
1.设置两个临界点,根据这两个点将直线分成三段
2.根据点计算出三条线段的斜率
3.根据斜率和点,计算出三条线段的y方向的偏移值
4.定义一个大小256的数组,作为表存放每个灰度值在不同线段中的频率
5.根据数组(表)填充到目标图像中
6.显示图像
三、源码
void dividedLinearStrength(cv::Mat& matInput, cv::Mat& matOutput, float x1, float x2,float y1, float y2)
{
//计算直线参数
//L1
float fK1 = y1 / x1;
//L2
float fK2 = (y2 - y1) / (x2- x1);
float fC2 = y2 - fK2 * x2;
//L3
float fK3 = (255.0f - y2) / (255.0f - x2);
float fC3 = 255.0f - fK3 * 255.0f;
//建立查询表
std::vector<unsigned char> loolUpTable(256);
for (size_t m = 0; m < 256; m++)
{
if (m < x1)
{
loolUpTable[m] = static_cast<unsigned char>(m * fK1);
}
else if (m > x2)
{
loolUpTable[m] = static_cast<unsigned char>(m * fK3 + fC3);
}
else
{
loolUpTable[m] = static_cast<unsigned char>(m * fK2 + fC2);
}
}
//构造输出图像
matOutput = cv::Mat::zeros(matInput.rows, matInput.cols, matInput.type());
//灰度映射
for (int i = 0; i < matInput.rows; i++)
{
for (int j = 0; j < matInput.cols; j++)
{
Vec3b* pInput = matInput.ptr<Vec3b>(i);
for (int c = 0; c < matInput.channels(); c++) {
//查表gamma变换
matOutput.at<Vec3b>(i, j).val[c] = loolUpTable[pInput[j].val[c]];
}
}
}
}
四、结果图
原文链接: https://www.cnblogs.com/yaoguang-willZ/p/14737717.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/210300
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!