分段線性拉伸
一、目的與原理
(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]]; } } } }
四、結果圖