分段线性拉伸
分段线性拉伸
一、目的与原理
(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]]; } } } }
四、结果图