數字圖像處理(MATLAB版)學習筆記(2)——第2章 灰度變換與空間濾波


0、小敘閑言

續第一章之后,對數字圖像和圖像處理略有了解。第二章內容有不少,書中編寫了很多的函數,還是一樣,只要沉下心看看,理清楚結構,看明白功能,個人覺得很容易看明白。同時書中的代碼都有很多的注釋,更加減少我們看代碼的難度。耐心,靜心,定會有所收獲。

1、本章整體結構

本章內容很多,也有很多的數學知識,個人在學習的時候,碰到了好多困難,畢竟不是科班出生,而且也沒有學習過數字信號處理,還好,線性代數和概率論學得還可以,但依舊有不少不理解的地方。下面也只能整理一下書中的知識要點,以后有新的領悟再來更新,看下面一章,關於離散傅里葉變換,好像更難。

2、書中例子

例2.1 主要是使用函數imadjust,來熟悉一下灰度處理,體驗一把

>> imread('myimage.jpg');
>> f=imread('myimage.jpg');
>> g1 = imadjust(f, [0 1], [1 0]);
>> imshow(g1);
>> imshow(f);
>> g2 = imadjust(f, [0.5 0.75], [0 1]);
>> figure;imshow(g2);
>> g3 = imadjust(f, [], [],2);
>> figure;imshow(g3);

處理前后效果,還可以,f到g1的變換,就是對像素值進行了反轉,也就是書中所講的負片效果,對醫學很有用。

g2圖是將[0.5 0.75]間的像素線性變換到[0 1]之間,也就是進行了放大。那么這里有點疑問,我們的圖像像素幅值區間不可能只是有[0.5 0.75],這個參數的意義到底是什么呢?我對書中的理解如下,上面圖中所用到的是uint8類型圖像,因此圖像幅值區間是[0 255],有一點編程基礎的都應該清楚。所以對應uint8類型,它的實際區間為[0.5 0.75]*255=[127.5  191.25]。如果是對應是uint16類型,那么他的實際區間為[0.5 0.75]*(2^16-1)=[32767 49151],也就是只取區間[32767 49151]像素幅值。再回到imadjust(f, [0.5 0.75], [0 1]),也就是將區間[127.5  191.25]映射到[0 255],怎么一個映射法呢?默認的就是線性對應,由兩點(兩個區間形成兩點)確定一條直線。如下圖所示:

那么問題又來了,如果是區間[0.5 0.75]映射到[1 0]又是如何理解的呢,其實是一樣的道理,做好點對點的對應關系,求出線性函數即可。如下圖所示的對應關系,這也就解釋了g1圖效果的原因,從[0 1]映射到[1 0],就是斜率為-1,x取值范圍為[0 255],完全就是一個線性明暗反轉操作。

Low_High=strechlim(f),就是幫我們找到圖像f中的像素幅值的最大值和最小值,如果f是一個單值圖像,那么Low_High就是一個行向量(1*2的矩陣),如果f是一個彩色圖像,那么Low_High就是一個3*2的矩陣。當我們找到f圖像的最小,最大像素幅值后,再將其映射到整個像素區間[0 1],也就是書中所講,實現對比度拉伸,可以得到不錯的效果。如下圖,從A圖到D圖,D圖就是使用了strechlim(f),然后使用D=imadjust(f,Low_High,[0 1]);得到的圖像,很是清晰。

書中的一個tofloat函數,很短,但寫得很棒,我讀了一下,並添加了一些自己的注釋,代碼如下。

 1 function [out, revertclass] = tofloat(in)  2 %out=輸入的圖像參數(in)轉化為float型數據點  3 %revertclass=一個函數句柄可以將類型轉回去  4 
 5 identity = @(x) x;        %一個匿名函數的句柄,表示自身  6 tosingle = @im2single;    %普通函數句柄 理解為函數指針也行  7 tabel = {  8         'uint8', tosingle, @im2uint8  9         'uint16', tosingle, @im2uint16 10         'int16', tosingle, @im2uint16 11         'int16', tosingle, @logical 12         'double', identity, identity 13         'single', identity, identity 14 }; 15 %在單元矩陣的第1列中找到輸入參數類型的名字 16 classIndex = find(strcmp(class(in), tabel(:, 1))); 17 
18 if isempty(classIndex) 19     error('Unspported input image class.'); 20 end 21 %在單元矩陣的第2列中找到索引處轉為flaot型的函數句柄,進行轉換 22 out = tabel{classIndex, 2}(in); 23 %在單元矩陣的第3列中找到索引處反轉為原來類型函數句柄,進行轉換 24 revertclass = tabel{classIndex, 3};

 運用例中的代碼做兩個圖看看,練練手,效果如下:

h=imhist(f,25);
horz = linspace(0,255,25);
subplot(1,2,1);bar(horz,h);
subplot(1,2,2);stem(horz, h, 'fill');

 

3、個人對書中一些知識的理解

書中intrans函數的的結構如下,書中寫了比較長的代碼,但並不復雜。只是在下面結構基礎上添加了一些邏輯判斷,增加了代碼的長度,算法不復雜。

本質就是對前面灰度變換方法的一個綜合,書中函數代碼寫了很長,其實都很容易,大部分代碼都是在做一個判斷,減少函數的bug。

書中重新編寫的g = gscale(f, method, low, high)函數,也就是實現前文所講的,灰度全尺度拉伸變換,個人覺得其實配合,stretchlim函數和imadjust可以輕松完成此功能。

心得總結

學習本章,深深感受好數學功底太重要了,很多理論如果對數學沒有一定的了解,很難理解原理。只能掌握一些關於圖像處理的方法。這跟當年學習單片機是一樣的,很多的電路原理都不太清楚,但是照着別人的方法和步驟來編程,一樣可以取得想要的效果。當使用單片機多了,接觸得更多了,慢慢以也就理解了。目前學習數字圖像處理的我,正像是當年第一次接觸單片機一樣。很多圖像處理的算法,雖然書上說了,但我還是不理解,只能照着書上的來,然后也得到了書上的效果。

在知乎上搜索如何學習數字圖像處理這一話題時,有很多人跟我一樣,也是不能理解其中的算法原理,有一些知乎的大神也給出了建議,第一次學習,書中諸多難以理解的算法,暫且可不用刨根問底。先掌握數字圖像處理這一技能,而后理解數字圖像處理這一心法,最后化為自己的內功。自身不是天才,無法一次就能掌握。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM