Matlab影像處理系列1———線性變換和長條圖均衡,matlab線性變換
註:本系列來自於影像處理課程實驗,用Matlab實現最基本的影像處理演算法
映像點處理是影像處理系列的基礎,主要用於讓我們熟悉Matlab影像處理的編程環境。灰階線性變換和灰階展開是對像素灰階值的變換操作,長條圖是對像素灰階值的統計,長條圖均衡是對灰階值分布的變換。
1.灰階線性變換(1)線性變換函數
原圖向灰階值為g,通過線性函數f(x)=kx+b轉換為f(g)得到灰階的線性變換。
(2)代碼實現
Matlab中支援矩陣作為函數參數傳入,定義一個線性轉換函式,利用Matlab矩陣操作,用一行代碼即可對整個二維映像矩陣中所有點的灰階進行線性變換:
function [ new ] = LinearTransformFunc( original, k, d ) new = original * k + d;end
其中k和d是線性函數的斜率和截距,由使用者輸入指定,使用者輸入為空白時賦予預設值:
input函數擷取使用者輸入
isempty判斷使用者輸入是否為空白:
k = input('please input the slope(k) of grayscale linear transformation function:\n');b = input('please input the intercept(b) of grayscale linear transformation function:\n');if isempty(k) k = 1;endif isempty(b) b = 0;end
變換映像名也可以由使用者input指定,預設為lena圖:
imread讀出圖片,傳回值第一個是我們需要的灰階圖(二維矩陣)
- 對變換後的灰階圖,用
imshow在figure中顯示映像
name = input('please input the name of image:\n');if isempty(name) name = 'lena'; endoriginal = imread(strcat('../exp/', name, '.bmp'));transformed = LinearTransformFunc(original, k, b);figureimshow(transformed)
在這個實驗的操作中說明如何讀入、顯示,後面實驗不在贅述
(3)運行結果
利用subplot作圖,把原圖和線性變換後的映像對比,線性變換函數是f(x)=2x+10:
左圖是原映像,右圖是線性變換後映像。
2.灰階展開變換(1)灰階展開變換和線性分段函數
灰階展開變換和線性變換相似,只是是將灰階值做分段線性變換。分段函數控制點(x1,y1)和(x2,y2):
(2)代碼實現
整個程式使用者介面和流程和線性變換相同,只是需要使用者輸入兩個控制點,並傳入以下的分段線性變換函數:
function [ new ] = StretchFunc(original, x1, y1, x2, y2 ) new = original; w = size(new, 1); h = size(new, 2); k1 = y1 / x1; dk1 = (y2 - y1) / (x2 - x1); dk2 = (255 - y2) / (255 - x2); for i = 1 : w for j = 1 : h x = new(i, j); if x < x1 new(i, j) = k1 * x; elseif x < x2 new(i, j) = dk1 * (x - x1) + y1; else new(i, j) = dk2 * (x - x2) + y2; end end endend
這裡不可避免要使用到for迴圈。
(3)運行結果
同樣對比原圖,預設控制點選取(-100,20)和(100,180)
3.灰階長條圖(1)灰階長條圖
灰階長條圖就是對映像中每個像素點的灰階值出現的頻數或頻率(歸一化)的統計,那麼我們直接遍曆整個映像統計出每個灰階值出現次數再做相應處理即可。
(2)代碼實現
首先需要遍曆統計灰階,我在GrayScaleStatistic函數裡完成統計,區間[low, high]是目標灰階統計區間,預設是[0,255]:
function [ result ] = GrayScaleStatistic( original, low, high ) w = size(original, 1); h = size(original, 2); result = zeros(1, high - low + 1); for i = 1 : w for j = 1 : h g = original(i, j); if g >= low && g <= high g = g - low + 1; result(g) = result(g) + 1; end end endend
然後就使用Matlab橫條圖作圖函數bar完成灰階圖作圖:
y = GrayScaleStatistic(original, low, high);x = low : 1 : high;bar(x, y)
對於題目要求的可輸入灰階區間顯示,我們要麼不統計區間[low, high]以外的灰階值,要麼直接全部統計但在作圖時用xlim函數限制x軸取值範圍:
xlim([low, high])
(3)運行結果
對比Matlab標準長條圖作圖函數histogram,結果如下:
也可以通過input輸入限定區間,這裡是[20,150]區間的灰階長條圖:
左右對比,效果一致。
4.長條圖均衡化(1)長條圖均衡演算法
長條圖均衡主要用於增強動態範圍偏小的映像的反差,其基本思想是把原始映像的長條圖變換為均勻分布,從而增強灰階值的動態範圍,以達到增強對比的效果。
長條圖均衡化演算法如下
(2)代碼實現
在指令碼中調用Normalize函數直接得到均衡化後的映像,再統計長條圖並顯示。
Normalize函數如下:
function [ new ] = Normalize( original, v ) s = sum(v); tv = v / s; l = length(v); for i = 2 : l tv(i) = tv(i) + tv(i - 1); end tk = uint8(255 * tv + 0.5); w = size(original, 1); h = size(original, 2); new = original; for i = 1 : w for j = 1 : h new(i, j) = tk(original(i, j) + 1); end endend
說明:
- tv先計算頻率長條圖,再通過累加得到累計長條圖
- tk根據累計長條圖計算新的灰階映射關係
- 最後遍曆整個映像把原灰階轉換成均衡化後的灰階值
其中有一下幾點需要注意,也是Matlab圖操作的注意點:
- Matlab預設類型是double,對灰階值賦值時注意強制轉換類型,保證類型一致
- Matlab座標起始從1開始,而灰階值是uint8的0-255,因此映射數組tk把原始灰階映射到變換後灰階時需要加1
(3)結果展示
pout.bmp是一副灰階分布較為集中的映像,因此映像對比不高,顯示較為模糊。使用長條圖均值化,分散灰階分布從而增強對比:
通過對比均衡先後長條圖分布,可以發現:
- 灰階分布不能完全平均化,是由於均值化演算法中運用了取整運算,而不是離散值的完全均衡化
- 得到的均衡化後長條圖走勢沒有發生變化,因此映像沒有失真