注:本系列來自於圖像處理課程實驗,用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;
end
if isempty(b)
b = 0;
end
變換圖像名也能夠由用戶input指定。默覺得lena圖:
imread讀出圖片。返回值第一個是我們須要的灰度圖(二維矩陣)- 對變換后的灰度圖,用
imshow在figure中顯示圖像
name = input('please input the name of image:\n');
if isempty(name)
name = 'lena';
end
original = imread(strcat('../exp/', name, '.bmp'));
transformed = LinearTransformFunc(original, k, b);
figure
imshow(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
end
end
這里不可避免要使用到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
end
end
然后就使用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)直方圖均衡算法
直方圖均衡主要用於增強動態范圍偏小的圖像的反差,其基本思想是把原始圖像的直方圖變換為均勻分布,從而增強灰度值的動態范圍,以達到增強對照度的效果。
直方圖均衡化算法例如以下
- 歸一化灰度頻數直方圖。得到頻率直方圖
sk - 用
sk計算頻率累計直方圖tk。 tk做取整擴展:tk = int[(L - 1) * tk + 0.5]。將直方圖灰度映射盡量滿整個灰度取值空間L- 確定變換映射關系
k->tk - 依據映射關系變換圖像灰度值
(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
end
end
說明:
- tv先計算頻率直方圖,再通過累加得到累計直方圖
- tk依據累計直方圖計算新的灰度映射關系
- 最后遍歷整個圖像把原灰度轉換成均衡化后的灰度值
當中有一下幾點須要注意,也是Matlab圖操作的注意點:
- Matlab默認類型是double。對灰度值賦值時注意強制轉換類型,保證類型一致
- Matlab坐標起始從1開始。而灰度值是uint8的0-255。因此映射數組tk把原始灰度映射到變換后灰度時須要加1
(3)結果展示
pout.bmp是一副灰度分布較為集中的圖像,因此圖像對照度不高,顯示較為模糊。使用直方圖均值化,分散灰度分布從而增強對照度:

通過對照均衡先后直方圖分布,能夠發現:
- 灰度分布不能全然平均化,是因為均值化算法中運用了取整運算,而不是離散值的全然均衡化
- 得到的均衡化后直方圖走勢沒有發生變化。因此圖像沒有失真
