- 數(shù)字圖像處理實(shí)驗(yàn)報(bào)告 推薦度:
- 相關(guān)推薦
數(shù)字圖像處理實(shí)驗(yàn)報(bào)告
數(shù)字圖像處理實(shí)驗(yàn)報(bào)告1
一. 實(shí)驗(yàn)內(nèi)容:
主要是圖像的幾何變換的編程實(shí)現(xiàn),具體包括圖像的讀取、改寫(xiě),圖像平移,圖像的鏡像,圖像的轉(zhuǎn)置,比例縮放,旋轉(zhuǎn)變換等.
具體要求如下:
1.編程實(shí)現(xiàn)圖像平移,要求平移后的圖像大小不變;
2.編程實(shí)現(xiàn)圖像的鏡像;
3.編程實(shí)現(xiàn)圖像的轉(zhuǎn)置;
4.編程實(shí)現(xiàn)圖像的比例縮放,要求分別用雙線性插值和最近鄰插值兩種方法來(lái)實(shí)
現(xiàn),并比較兩種方法的縮放效果;
5.編程實(shí)現(xiàn)以任意角度對(duì)圖像進(jìn)行旋轉(zhuǎn)變換,要求分別用雙線性插值和最近鄰插
值兩種方法來(lái)實(shí)現(xiàn),并比較兩種方法的旋轉(zhuǎn)效果.
二.實(shí)驗(yàn)?zāi)康暮鸵饬x:
本實(shí)驗(yàn)的目的是使學(xué)生熟悉并掌握?qǐng)D像處理編程環(huán)境,掌握?qǐng)D像平移、鏡像、轉(zhuǎn)置和旋轉(zhuǎn)等幾何變換的方法,并能通過(guò)程序設(shè)計(jì)實(shí)現(xiàn)圖像文件的讀、寫(xiě)操作,及圖像平移、鏡像、轉(zhuǎn)置和旋轉(zhuǎn)等幾何變換的程序?qū)崿F(xiàn).
三.實(shí)驗(yàn)原理與主要框架:
3.1 實(shí)驗(yàn)所用編程環(huán)境:
Visual C++(簡(jiǎn)稱VC)是微軟公司提供的基于C/C++的應(yīng)用程序集成開(kāi)發(fā)工具.VC擁有豐富的功能和大量的擴(kuò)展庫(kù),使用它能有效的創(chuàng)建高性能的Windows應(yīng)用程序和Web應(yīng)用程序.
VC除了提供高效的C/C++編譯器外,還提供了大量的可重用類和組件,包括著名的微軟基礎(chǔ)類庫(kù)(MFC)和活動(dòng)模板類庫(kù)(ATL),因此它是軟件開(kāi)發(fā)人員不可多得的開(kāi)發(fā)工具.
VC豐富的功能和大量的擴(kuò)展庫(kù),類的重用特性以及它對(duì)函數(shù)庫(kù)、DLL庫(kù)的支持能使程序更好的模塊化,并且通過(guò)向?qū)С绦虼蟠蠛?jiǎn)化了庫(kù)資源的使用和應(yīng)用程序的開(kāi)發(fā),正由于VC具有明顯的優(yōu)勢(shì),因而我選擇了它來(lái)作為數(shù)字圖像幾何變換的開(kāi)發(fā)工具.
在本程序的開(kāi)發(fā)過(guò)程中,VC的核心知識(shí)、消息映射機(jī)制、對(duì)話框控件編程等都得到了生動(dòng)的體現(xiàn)和靈活的應(yīng)用.
3.2 實(shí)驗(yàn)處理的對(duì)象:256色的BMP(BIT MAP )格式圖像
BMP(BIT MAP )位圖的文件結(jié)構(gòu):
具體組成圖: BITMAPFILEHEADER
位圖文件頭
(只用于BMP文件) bfType=”BM” bfSize bfReserved1
bfReserved2
bfOffBits
biSize
biWidth
biHeight
biPlanes
biBitCount
biCompression
biSizeImage
biXPelsPerMeter
biYPelsPerMeter
biClrUsed
biClrImportant
單色DIB有2個(gè)表項(xiàng)
16色DIB有16個(gè)表項(xiàng)或更少
256色DIB有256個(gè)表項(xiàng)或更少
真彩色DIB沒(méi)有調(diào)色板
每個(gè)表項(xiàng)長(zhǎng)度為4字節(jié)(32位)
像素按照每行每列的順序排列
每一行的字節(jié)數(shù)必須是4的整數(shù)
倍BITMAPINFOHEADER 位圖信息頭 Palette 調(diào)色板 DIB Pixels DIB圖像數(shù)據(jù)
1. BMP文件組成
BMP文件由文件頭、位圖信息頭、顏色信息和圖形數(shù)據(jù)四部分組成.
2. BMP文件頭
BMP文件頭數(shù)據(jù)結(jié)構(gòu)含有BMP文件的類型(必須為BMP)、文件大小(以字節(jié)為單位)、位圖文件保留字(必須為0)和位圖起始位置(以相對(duì)于位圖
文件頭的偏移量表示)等信息.
3. 位圖信息頭
BMP位圖信息頭數(shù)據(jù)用于說(shuō)明位圖的尺寸(寬度,高度等都是以像素為單位,大小
以字節(jié)為單位, 水平和垂直分辨率以每米像素?cái)?shù)為單位) ,目標(biāo)設(shè)備的級(jí)別,每個(gè)像素所需的位數(shù), 位圖壓縮類型(必須是 0)等信息.
4. 顏色表
顏色表用于說(shuō)明位圖中的顏色,它有若干個(gè)表項(xiàng),每一個(gè)表項(xiàng)是一個(gè)RGBQUAD
類型的'結(jié)構(gòu),定義一種顏色.具體包含藍(lán)色、紅色、綠色的亮度(值范圍為0-255)
位圖信息頭和顏色表組成位圖信息
5. 位圖數(shù)據(jù)
位圖數(shù)據(jù)記錄了位圖的每一個(gè)像素值,記錄順序是在掃描行內(nèi)是從左到右,掃描
行之間是從下到上.
Windows規(guī)定一個(gè)掃描行所占的字節(jié)數(shù)必須是 4的倍數(shù)(即以long為單位),不足的以0填充.
3.3 BMP(BIT MAP )位圖的顯示:
①一般顯示方法:
1. 申請(qǐng)內(nèi)存空間用于存放位圖文件
2. 位圖文件讀入所申請(qǐng)內(nèi)存空間中
3. 在函數(shù)中用創(chuàng)建顯示用位圖, 用函數(shù)創(chuàng)建兼容DC,用函數(shù)選擇顯示刪除位圖
但以上方法的缺點(diǎn)是: 1)顯示速度慢; 2) 內(nèi)存占用大; 3) 位圖在縮小顯示時(shí)圖形失真大,(可通過(guò)安裝字體平滑軟件來(lái)解決); 4) 在低顏色位數(shù)的設(shè)備上(如256顯示模式)顯示高顏色位數(shù)的圖形(如真彩色)圖形失真嚴(yán)重.
②BMP位圖縮放顯示 :
用視頻函數(shù)來(lái)顯示位圖,內(nèi)存占用少,速度快,而且還可以對(duì)圖形進(jìn)行淡化(Dithering )處理.淡化處理是一種圖形算法,可以用來(lái)在一個(gè)支持比圖像所用顏色要少的設(shè)備上顯示彩色圖像.BMP位圖顯示方法如下:
1. 打開(kāi)視頻函數(shù),一般放在在構(gòu)造函數(shù)中
2. 申請(qǐng)內(nèi)存空間用于存放位圖文件
3. 位圖文件讀入所申請(qǐng)內(nèi)存空間中
4. 在 函數(shù)中 顯示位圖
5. 關(guān)閉視頻函數(shù) ,一般放在在析構(gòu)函數(shù)中
以上方法的優(yōu)點(diǎn)是: 1)顯示速度快; 2) 內(nèi)存占用少; 3) 縮放顯示時(shí)圖形失真小,4) 在低顏色位數(shù)的設(shè)備上顯示高顏色位數(shù)的圖形圖形時(shí)失真小; 5) 通過(guò)直接處理位圖數(shù)據(jù),可以制作簡(jiǎn)單動(dòng)畫(huà).
3.4 程序中用到的訪問(wèn)函數(shù)
Windows支持一些重要的DIB訪問(wèn)函數(shù),但是這些函數(shù)都還沒(méi)有被封裝到MFC中,這些函數(shù)主要有:
1. SetDIBitsToDevice函數(shù):該函數(shù)可以直接在顯示器或打印機(jī)上顯示DIB. 在顯
示時(shí)不進(jìn)行縮放處理.
2. StretchDIBits函數(shù):該函數(shù)可以縮放顯示DIB于顯示器和打印機(jī)上.
3. GetDIBits函數(shù):還函數(shù)利用申請(qǐng)到的內(nèi)存,由GDI位圖來(lái)構(gòu)造DIB.通過(guò)該函數(shù),
可以對(duì)DIB的格式進(jìn)行控制,可以指定每個(gè)像素顏色的位數(shù),而且可以指定是否進(jìn)行壓縮.
4. CreateDIBitmap函數(shù):利用該函數(shù)可以從DIB出發(fā)來(lái)創(chuàng)建GDI位圖.
5. CreateDIBSection函數(shù):該函數(shù)能創(chuàng)建一種特殊的DIB,稱為DIB項(xiàng),然后返回
一個(gè)GDI位圖句柄.
6. LoadImage函數(shù):該函數(shù)可以直接從磁盤文件中讀入一個(gè)位圖,并返回一個(gè)DIB
句柄.
7. DrawDibDraw函數(shù):Windows提供了窗口視頻(VFW)組件,Visual C++支持該
組件.VFW中的DrawDibDraw函數(shù)是一個(gè)可以替代StretchDIBits的函數(shù).它的最主要的優(yōu)點(diǎn)是可以使用抖動(dòng)顏色,并且提高顯示DIB的速度,缺點(diǎn)是必須將VFW代碼連接到進(jìn)程中.
3.5 圖像的幾何變換
圖像的幾何變換,通常包括圖像的平移、圖像的鏡像變換、圖像的轉(zhuǎn)置、圖像的縮放和圖像的旋轉(zhuǎn)等.
數(shù)字圖像處理實(shí)驗(yàn)報(bào)告2
一、實(shí)驗(yàn)的目的和意義
實(shí)驗(yàn)?zāi)康模罕緦?shí)驗(yàn)內(nèi)容旨在讓學(xué)生通過(guò)用VC等高級(jí)語(yǔ)言編寫(xiě)數(shù)字圖像處理的一些基本算法程序,來(lái)鞏固和掌握?qǐng)D像處理技術(shù)的基本技能,提高實(shí)際動(dòng)手能力,并通過(guò)實(shí)際編程了解圖像處理軟件的實(shí)現(xiàn)的基本原理。為學(xué)生進(jìn)一步學(xué)習(xí)數(shù)字?jǐn)z影測(cè)量、遙感和地理信息系統(tǒng)等專業(yè)課程以及應(yīng)用圖像處理解決實(shí)際問(wèn)題奠定基礎(chǔ)。
二、實(shí)驗(yàn)原理和方法
(1) Raw格式到BMP格式的轉(zhuǎn)換:
Raw格式:Raw格式文件是按照數(shù)字圖像組成的二維矩陣,將像素按行列號(hào)順序存儲(chǔ)在文件中。這種文件只含有圖像像素?cái)?shù)據(jù),不含有信息頭,因此,在讀圖像時(shí),需要根據(jù)文件大小,計(jì)算圖像所包含的行列號(hào),或者需要事先知道圖像大小(矩陣大小)。RAW文件按圖像上行到下行、左列到右列順序存儲(chǔ)。
BMP格式:BMP文件數(shù)據(jù)區(qū)按圖像上下行到上行、左列列到右列順序存儲(chǔ)到數(shù)據(jù)區(qū)。BMP文件由文件頭、信息頭、顏色表、數(shù)據(jù)區(qū)四個(gè)部分組成。
做Raw格式文件到BMP格式文件的轉(zhuǎn)化,先要為BMP格式文件申請(qǐng)四部分的內(nèi)存:文件頭,位圖信息頭,顏色表,圖象數(shù)據(jù),然后根據(jù)輸入值以及Raw文件信息,BMP格式文件信息計(jì)算出這幾部分的值,賦給他們,寫(xiě)到BMP文件中去。
(2) 灰度圖象的線性拉伸:
灰度變化是點(diǎn)運(yùn)算,將原圖象的每個(gè)像素的灰度值改成線性變化之后的灰度即可。
灰度的線性變換就是指圖像的中所有點(diǎn)的灰度按照線性灰度變換函數(shù)進(jìn)行變換;叶茸儞Q方程如下:
該方程為線性方程。式中參數(shù) 為輸入圖像的像素的灰度值,參數(shù) 為輸出圖像的
灰度值。
設(shè)原圖象的灰度范圍為[a,b],變化之后的范圍為[a’,b’],則:
fA=(b’-a’)/(b-a)
fB=-(b’-a’)/(b-a)*a+a’
如果算出來(lái)的值大于255,則讓它等于255,小于0則讓其等于0。
(3) 局部處理(3*3高通濾波,3*3低通濾波):
局部處理在處理某一像素時(shí),利用與該像素相鄰的一組像素,經(jīng)過(guò)某種變換得到處理后圖像中某一點(diǎn)的像素值。目標(biāo)像素的鄰域一般是由像素組成的二維矩陣,該矩陣的大小為奇數(shù),目標(biāo)像素位于該矩陣的中央,即目標(biāo)像素就是區(qū)域的中心像素。經(jīng)過(guò)處理后,目標(biāo)像素的值為經(jīng)過(guò)特定算法計(jì)算后所得的結(jié)果。
實(shí)際上都是利用卷積來(lái)實(shí)現(xiàn)的,卷積往往用一個(gè)矩陣表示,將矩陣的中心對(duì)齊某個(gè)像素,矩陣中的值乘到相應(yīng)的像素中去,然后將所有乘積加起來(lái)就得到中心像素的灰度值。邊界像素不做處理,仍為原來(lái)的灰度值。求出的像素灰度值若超過(guò)[0~255],則向離其最近的屬于該范圍的像素值靠攏。
3*3低通濾波的算子見(jiàn)表1。
3*3高通濾波的算子見(jiàn)表2。
表格 1
1/9
1/9
1/9
1/9
1/9
1/9
1/9
1/9
1/9
表格 2
-1
-1
-1
-1
9
-1
-1
-1
-1
(4) 圖象幾何處理(圖象平移,圖象縮放):
對(duì)于圖像平移來(lái)說(shuō),若平移量是(tx,ty),像素在原圖像中的坐標(biāo)為(x0,y0),則變化后的坐標(biāo)為(x1,y1),x1=x0+tx,y1=y0+ty。平移只需改變像素的灰度值,不必改變位圖信息頭和調(diào)色板內(nèi)容。
對(duì)于圖像縮放,假設(shè)放大因子為ratio,縮放的變換矩陣為:
圖像信息頭中新圖像的寬度和高度都變?yōu)樵瓉?lái)寬度和高度分別與水平垂直比例的乘積,圖像大小變?yōu)樾聦挾?變?yōu)?的整數(shù)倍)與新高度的乘積。
(5) 灰度圖象中值濾波:
中值濾波也屬于局部處理的一種,將窗口中的各個(gè)像素排序之后排序,取中值賦給模板中心的像素,所以窗口中個(gè)數(shù)一般是基數(shù)。
我用的中值濾波窗口是十字絲的9個(gè)數(shù)的窗口。
(6) 灰度圖象邊緣檢測(cè):
邊緣檢測(cè)有三種算子:Roberts,Prewit,Sobel。三種算子都是做一階差分的,通過(guò)算子算出各個(gè)像素的梯度值,將水平梯度的絕對(duì)值和垂直梯度的絕對(duì)值相加,若此梯度值大于某個(gè)閾值,則將其灰度值賦為255,否則賦為0。
(7) 圖象旋轉(zhuǎn):
圖像旋轉(zhuǎn)一般是以圖像中心為中心順時(shí)針旋轉(zhuǎn),利用圖像的四個(gè)角點(diǎn)求出圖像旋轉(zhuǎn)后的大小。
先計(jì)算以圖像中心為原點(diǎn)坐標(biāo)系下原圖像四個(gè)角點(diǎn)的坐標(biāo)值,按照旋轉(zhuǎn)矩陣計(jì)算其旋轉(zhuǎn)之后的坐標(biāo)值,根據(jù)四個(gè)角點(diǎn)的新坐標(biāo)值計(jì)算出最大寬度和高度作為新圖像的寬度和高度值,按照計(jì)算值修改位圖信息頭,申請(qǐng)一塊新內(nèi)存,存儲(chǔ)旋轉(zhuǎn)后圖像的灰度值。
旋轉(zhuǎn)矩陣如下:
同樣要求各個(gè)像素在原圖像中的坐標(biāo),先將新圖像的坐標(biāo)系平移到圖像中心,做逆時(shí)針旋轉(zhuǎn),然后再平移到屏幕左上角,然后將原圖像對(duì)應(yīng)坐標(biāo)的值賦給新圖像。
(8) 圖象二值化:
判斷分析法:假定圖像的灰度區(qū)間為[0,L-1],則選擇一閾值T 將圖像的像素分為兩組。
為最大值所對(duì)應(yīng)的T,就是所求判斷分析法的分割閾值。
搜尋到閾值之后,灰度值小于閾值的像素賦0,其他的賦1,修改文件信息頭,調(diào)色板,申請(qǐng)新內(nèi)存。
(9) 圖象直方圖:
統(tǒng)計(jì)各灰度值出現(xiàn)的頻數(shù),以及像素的總個(gè)數(shù),用頻數(shù)除以總個(gè)數(shù)作為頻率,以灰度值作為橫坐標(biāo),頻率作為縱坐標(biāo)繪圖。
三、實(shí)驗(yàn)過(guò)程和步驟
首先要建立一個(gè)基于MFC的多文檔工程,將視圖基類改為滾動(dòng)視圖,以自己的學(xué)號(hào)命名。
我用的是書(shū)上給的CDib類,類里面有獲取BMP寬度,高度的函數(shù),有指向位圖信息頭的指針,指向圖象數(shù)據(jù)的指針,因此我在文檔類(Doc類)里定義了一個(gè)CDib類的對(duì)象,打開(kāi)以及保存文件的時(shí)候利用這個(gè)對(duì)象去調(diào)用CDib里讀取與存儲(chǔ)文件的函數(shù),并且可以利用這個(gè)對(duì)象的兩個(gè)指針對(duì)打開(kāi)的圖象進(jìn)行各種操作。
1.Raw格式到BMP格式的轉(zhuǎn)換:
首先建立一個(gè)RawToBMP的對(duì)話框,在上面加上四個(gè)編輯框(一個(gè)輸入打開(kāi)文件的路徑一個(gè)輸入保存文件的路徑,另兩個(gè)),兩個(gè)按鈕,以及默認(rèn)的確認(rèn),取消按鈕。利用類向?qū)Р迦氪藢?duì)話框類,并且為前兩個(gè)編輯框定義CString的兩個(gè)變量,用來(lái)存儲(chǔ)打開(kāi)與保存文件的路徑。同時(shí)為兩個(gè)瀏覽按鈕添加消息響應(yīng)函數(shù),在消息函數(shù)里創(chuàng)建CFileDialog對(duì)象,利用此對(duì)象的函數(shù)將兩個(gè)路徑值賦給前兩個(gè)編輯框的成員變量。再為OK鍵添加消息響應(yīng)函數(shù),分別定義BMP格式文件前三部分?jǐn)?shù)據(jù)變量,計(jì)算出各變量的值,并且利用一個(gè)CFile對(duì)象獲取Raw圖象的數(shù)據(jù),利用另一個(gè)CFile對(duì)象將數(shù)據(jù)存儲(chǔ)到所輸入的路徑的文件中去,CFile對(duì)象的Read函數(shù)會(huì)自動(dòng)創(chuàng)建一個(gè)文件。
然后在菜單上新建一個(gè)菜單,為菜單添加消息響應(yīng)函數(shù),在其消息響應(yīng)函數(shù)里創(chuàng)建RowToBMP對(duì)話框。這樣點(diǎn)擊菜單后就會(huì)彈出一個(gè)對(duì)話框,按確定鍵之后就可以讀取Raw文件并且存儲(chǔ)BMP文件,完成整個(gè)消息循環(huán)。
2.灰度圖象的線性拉伸:
創(chuàng)建一個(gè)對(duì)話框來(lái)輸入變化后的灰度值,為對(duì)話框的兩個(gè)編輯框定義成員變量,在文檔類中添加處理函數(shù),按照對(duì)話框輸入值計(jì)算出fA與fB,做一個(gè)循環(huán),將0到255的灰度值,計(jì)算出拉伸后的灰度值(超限情況特殊處理),存放在下標(biāo)為此值的'一個(gè)數(shù)組中,然后利用文檔類的中定義的CDib類的成員變量m_DIB,獲得當(dāng)前打開(kāi)的圖像指向圖像數(shù)據(jù)部分的指針m_DIB.m_pBits,在數(shù)組中查出每個(gè)像素變化后的灰度值,并將此值賦給指針m_pBits指向的內(nèi)存。刷新視圖。
然后在菜單中加上線性拉伸的菜單,為該菜單的ID添加消息響應(yīng)函數(shù),在該函數(shù)中創(chuàng)建對(duì)話框,并調(diào)用文檔類線性拉伸的函數(shù),將對(duì)話框的兩個(gè)成員變量傳給此函數(shù)。
3.局部處理:
在文檔類里添加低通濾波和高通濾波的成員函數(shù),在函數(shù)中使用m_DIB對(duì)象中指向圖像數(shù)據(jù)部分的指針m_pBits,首先申請(qǐng)一個(gè)新內(nèi)存,將原來(lái)圖像的灰度值存儲(chǔ)起來(lái),然后定義9個(gè)BYTE類型的指針,利用雙重嵌套循環(huán),在循環(huán)中每次用這9個(gè)指針指向復(fù)制圖像對(duì)應(yīng)模板中的9個(gè)數(shù),然后按照模板中的數(shù)值計(jì)算出中心像素的灰度值,判斷是否超過(guò)范圍,如果超過(guò)范圍則做相應(yīng)的處理,否則將此值直接賦給m_pBits中對(duì)應(yīng)的中心像素。循環(huán)之后刷新視圖。
添加局部處理的菜單,為菜單設(shè)置消息響應(yīng)函數(shù),在菜單消息響應(yīng)函數(shù)中調(diào)用文檔類的函數(shù),完成對(duì)m_DIB的處理。
4.圖像幾何變換:
建立平移對(duì)話框,定義兩個(gè)成員變量,分別存儲(chǔ)輸入的水平位移和垂直位移。
在文檔類里添加平移函數(shù),申請(qǐng)一塊新內(nèi)存復(fù)制原圖像的信息,在函數(shù)中將
外層循環(huán)變量i視為縱坐標(biāo),內(nèi)層循環(huán)變量j視為橫坐標(biāo),通過(guò)雙重循環(huán),對(duì)每個(gè)像素,求出其在原圖像中的坐標(biāo)(i0,j0),將復(fù)制圖像中的對(duì)應(yīng)(i0,j0)的像素灰度值賦給m_DIB.m_pBits指針中的圖像。如果在原圖像中找不到該像素,置為背景色。刷新視圖。
在菜單中添加圖像平移菜單,并為該菜單添加消息響應(yīng)函數(shù),在此函數(shù)中創(chuàng)建平移對(duì)話框,調(diào)用文檔類的平移函數(shù),將對(duì)話框的成員變量傳入該函數(shù)。
建立縮放對(duì)話框類,為此類定義兩個(gè)成員變量,存儲(chǔ)輸入的水平縮放因子和垂直縮放因子。
再在文檔類中添加縮放函數(shù),利用m_DIB.m_pBMI(指向位圖信息頭的指針),修改位圖信息頭中的寬度,高度,圖像大小。計(jì)算出新圖像的大小,申請(qǐng)一塊新內(nèi)存存儲(chǔ)新圖像,同平移函數(shù)一樣,計(jì)算出每個(gè)像素在原圖像中的坐標(biāo),i0=i/PRatio,j0=j/VRatio,PRatio與VRatio分別為水平縮放因子和垂直縮放因子。將原圖像中對(duì)應(yīng)坐標(biāo)的灰度值賦給新內(nèi)存,然后將m_DIB.m_pBits(指向圖像數(shù)據(jù)的指針)指向新內(nèi)存,刷新視圖。
5.中值濾波:
在文檔類中添加兩個(gè)成員函數(shù)。一個(gè)用來(lái)把傳入的指針里的內(nèi)容排序,一個(gè)用來(lái)做中值濾波。也要申請(qǐng)一塊新內(nèi)存來(lái)復(fù)制原圖像的信息,雙重嵌套循環(huán),邊界像素不處理,對(duì)每個(gè)像素,使用一個(gè)大小為9個(gè)字節(jié)的數(shù)組來(lái)存放復(fù)制圖像窗口中各像素值,然后將數(shù)組首地址傳入排序的函數(shù)中,將中間的值賦給當(dāng)前圖像窗口中心的像素。排序函數(shù)我用的是快速排序法。
在菜單中添加中值濾波菜單項(xiàng),為其添加消息響應(yīng)函數(shù),調(diào)用文檔類的中值濾波函數(shù)。
6.邊緣檢測(cè):
在文檔類中定義三個(gè)函數(shù),分別為Roberts,Prewit,Sobel算子處理函數(shù),處理時(shí),先申請(qǐng)新內(nèi)存復(fù)制原來(lái)圖像信息,邊界像素不作處理,對(duì)每個(gè)像素值,求出其在復(fù)制圖像中的梯度,判斷,若梯度值大于150(這個(gè)是我自己定的),則將灰度值賦為255,否則置零。
菜單中添加邊緣檢測(cè)菜單,置屬性為Pop—up,添加三個(gè)下一級(jí)菜單,分別為Roberts,Prewit,Sobel,各個(gè)菜單的消息響應(yīng)函數(shù)中調(diào)用文檔類中各自的處理函數(shù)。
7.圖像旋轉(zhuǎn):
創(chuàng)建一個(gè)對(duì)話框輸入旋轉(zhuǎn)角度,在文檔類中添加成員函數(shù)。
先將角度化為弧度值。
計(jì)算原圖像四個(gè)角點(diǎn)的坐標(biāo),以及新圖像四個(gè)角點(diǎn)的坐標(biāo)。
根據(jù)新圖像四個(gè)角點(diǎn)的坐標(biāo),取對(duì)角線上兩個(gè)點(diǎn)橫坐標(biāo)差值較大值作為寬度,縱坐標(biāo)差值較大值作為高度。
根據(jù)計(jì)算出來(lái)的高度和寬度修改文件信息頭,并且申請(qǐng)內(nèi)存存儲(chǔ)新圖像。
計(jì)算每點(diǎn)的像素在原來(lái)圖像中的坐標(biāo)從而獲取其灰度值,寫(xiě)入新內(nèi)存。
將m_DIB.m_pBits指向該新內(nèi)存。刷新視圖。
添加圖像旋轉(zhuǎn)菜單,在菜單響應(yīng)函數(shù)中創(chuàng)建對(duì)話框,調(diào)用文檔類中旋轉(zhuǎn)函數(shù),將對(duì)話框中獲取的角度傳給旋轉(zhuǎn)函數(shù)。
8.圖像二值化:
在文檔類添加一個(gè)成員函數(shù),根據(jù)傳人的圖像和閾值返回組間方差和組內(nèi)方差的比值。
再添加一個(gè)成員函數(shù),進(jìn)行二值化。
在函數(shù)中:
計(jì)算新BMP文件的大小,申請(qǐng)一塊新內(nèi)存,存儲(chǔ)新的整個(gè)BMP文件的信息,將位圖信息頭中biBitCount置為1,調(diào)色板數(shù)組只有兩個(gè)兩個(gè)元素,下標(biāo)為0的三個(gè)灰度值都為0,下標(biāo)為1的三個(gè)灰度值為255。
從最大灰度值到最小灰度值之間搜尋上述函數(shù)返回值最大的值,作為閾值。
對(duì)每個(gè)像素,若其原來(lái)灰度值小于閾值,賦1,否則賦0。
將m_DIB,m_pBits指向新內(nèi)存的圖像數(shù)據(jù)部分,m_DIB.m_pBMI指向位圖信息頭。
9.圖像直方圖:
為文檔類添加一個(gè)int型指針成員變量m_pGray,在構(gòu)造函數(shù)中將該指針賦空,在文檔類中定義了一個(gè)函數(shù),統(tǒng)計(jì)各個(gè)灰度值出現(xiàn)的頻數(shù),申請(qǐng)一個(gè)內(nèi)存,存儲(chǔ)在這個(gè)內(nèi)存中,并將m_pGray指向它。
創(chuàng)建一個(gè)畫(huà)直方圖的對(duì)話框,添加Picture控件,在控件里調(diào)用文檔類成員變量,畫(huà)直方圖。添加一個(gè)滾動(dòng)條,用來(lái)確定閾值,為滾動(dòng)條添加消息響應(yīng)函數(shù),按照滾動(dòng)條的值進(jìn)行二值化。
在菜單中添加直方圖菜單,添加消息響應(yīng)函數(shù),在響應(yīng)函數(shù)中創(chuàng)建直方圖對(duì)話框?qū)ο蟆?/p>
最后,因?yàn)槲议_(kāi)始做工程的時(shí)候沒(méi)有把菜單設(shè)計(jì)好,做得有點(diǎn)亂,所以,我又在View里添加WM_CONTEXTMENU消息響應(yīng)函數(shù),在函數(shù)體內(nèi)用CMenu類來(lái)實(shí)現(xiàn)彈出菜單。
四、結(jié)果分析與評(píng)價(jià)
(1)Raw格式到BMP格式的轉(zhuǎn)換:效果見(jiàn)圖1。
圖表 1
老師說(shuō)在轉(zhuǎn)化的時(shí)候后面用一個(gè)循環(huán)會(huì)降低效率,但是實(shí)際上只要寬度是4的整數(shù)倍,后面的循環(huán)就不會(huì)做了。所以這個(gè)算法效率我覺(jué)得還行吧。
(2)線性變化:輸入線性變化范圍10~20,效果見(jiàn)圖2。
圖表 2
用了線性查找表之后,這個(gè)算法的效率應(yīng)該會(huì)高很多,但是我的算法里是線性表從0~255都有變化之后的值,實(shí)際上,如果圖片的灰度范圍小一些的話,做了很多無(wú)用的計(jì)算,而且前面已經(jīng)搜尋過(guò)原圖像的最大最小灰度值了,所以線性表的生成循環(huán)可以只從最小灰度做到最大灰度。另外,我設(shè)計(jì)的算法里,如果最大值和最小值輸反了的話,程序會(huì)自動(dòng)交換他們的值,做這個(gè)可能就會(huì)多算一些東西了。
(3)低通濾波:效果見(jiàn)圖3。
圖表 3
取的是8鄰域內(nèi)的平均值,效果不是很好。
高通濾波:效果見(jiàn)圖4。
圖表 4
基本上我覺(jué)得邊緣還是有突出了吧。
中值濾波:效果見(jiàn)圖5。
圖表 5
這個(gè)中值濾波的效果我還是比較滿意的,因?yàn)榕判蛩砸{(diào)用其他函數(shù),我用了快速排序,而且用的是9個(gè)數(shù)的十字絲窗口,所以速度要比25個(gè)數(shù)的窗口快一些。平滑的效果出來(lái)還可以。
(4)邊緣檢測(cè):
Roberts算子:效果見(jiàn)圖6。
圖表 6
Prewit算子:效果見(jiàn)圖7。
圖表 7
Sobel算子:效果見(jiàn)圖8。
圖表 8
由于Prewit算子和Sobel算子都用了8個(gè)數(shù)去做,所以效果要好一些,相比之下,Sobel算子對(duì)這幅圖又要效果好些,應(yīng)該是對(duì)4鄰域賦予了更大權(quán)的緣故。但是后兩種算法計(jì)算量也要大一些。
(5)圖像平移:效果見(jiàn)圖9。
圖表 9
這個(gè)圖像平移量比較大,所以被裁切的也顯得不真實(shí)了。主要是因?yàn)槲业膱D像大小和坐標(biāo)都沒(méi)有變化,所以只在原來(lái)的圖像坐標(biāo)范圍內(nèi)顯示平移后的圖像,實(shí)際上,我既可以改變圖像的大小,并且為了節(jié)省計(jì)算,可以讓循環(huán)變量i和j從一個(gè)新的值開(kāi)始做計(jì)算,前面的全都賦背景色。
圖像縮放:水平比例0.4,垂直比例0.5,效果見(jiàn)圖10。
圖表 10
在此基礎(chǔ)上旋轉(zhuǎn):效果見(jiàn)圖11。
圖表 11
這幾種算法主要的計(jì)算量都在for循環(huán)內(nèi),所以要想優(yōu)化算法的話,必須簡(jiǎn)化循環(huán)里的計(jì)算。不過(guò)我的想法差不多跟書(shū)上的差不多,還沒(méi)有什么優(yōu)化。也許,這種優(yōu)化的算法需要看很多別人做的好程序才能慢慢自己學(xué)會(huì)吧。
(6)二值化(判斷分析法):效果見(jiàn)圖12。
圖表 12
實(shí)際上,我用直方圖看的最佳閾值應(yīng)該在100多左右,而我做的程序閾值好像偏小一些,所以效果不太好,我計(jì)算組間方差和組內(nèi)方差的時(shí)候調(diào)用了一個(gè)函數(shù)專門求閾值,可能這里的計(jì)算還是有一點(diǎn)問(wèn)題。而且在我的函數(shù)里,要256次調(diào)用這個(gè)函數(shù),又因?yàn)橛?jì)算機(jī)是按字節(jié)處理數(shù)據(jù)的,因此寫(xiě)圖像數(shù)據(jù)的時(shí)候要用每8個(gè)寫(xiě)到一個(gè)數(shù)組中,然后通過(guò)計(jì)算得到字節(jié)類型的值,這些都使得我的算法效率比較低,最后一個(gè)問(wèn)題,我覺(jué)得如果使用位運(yùn)算會(huì)快一些,但是前面的問(wèn)題還沒(méi)有想到比較好的解決方法。
(7)直方圖:效果見(jiàn)圖13。
這個(gè)圖像255的像素太多,如果我沒(méi)算錯(cuò)的話,量化應(yīng)該不是很好吧。
圖表 13
五、實(shí)驗(yàn)總結(jié)與體會(huì)
這次實(shí)驗(yàn)學(xué)到最大的東西,是自己總算有MFC編程的概念了,雖然自己VC++考試的分?jǐn)?shù)還不錯(cuò),但是里面的很多東西,不通過(guò)自己的編程時(shí)絕對(duì)不能真正理解。比如說(shuō)封裝性,這次用CDib的方便,很好地利用了類的封裝性。另外,比如MFC是基于消息響應(yīng)機(jī)制的,這就決定了,要利用鼠標(biāo)或者菜單響應(yīng)函數(shù)去實(shí)現(xiàn)功能,而用c語(yǔ)言編寫(xiě)程序的時(shí)候,完全是按主函數(shù)的線程來(lái)的。
另外,我也學(xué)會(huì)了調(diào)試的真正含義。以前都只知道那幾個(gè)按鍵是做什么用的,調(diào)試的真正目的,是根據(jù)自己的算法來(lái)檢驗(yàn)程序計(jì)算的各個(gè)值是否符合,從而可以很快速方便地查到自己的錯(cuò)誤。
自學(xué)也是很重要的一方面。實(shí)際上,在現(xiàn)在來(lái)說(shuō),用MSDN也不是很難的事了,我們不應(yīng)該被英文打到,而且現(xiàn)在,隨著對(duì)一些專有名詞熟悉了之后,看MSDN也容易一些了,萬(wàn)一不懂的函數(shù),也可以利用網(wǎng)絡(luò)查到很多函數(shù)功能用法的解釋。
剛開(kāi)始的時(shí)候做的是位圖的讀取和顯示,實(shí)在是不知從哪里做起,所以就照著實(shí)驗(yàn)書(shū)上敲了前面的部分,但是慢慢地也看懂了代碼的意思。所以后來(lái)的基本上都是自己做的了,但是算法還是基本上和書(shū)上差不多。不過(guò)自己編的時(shí)候還是有很多細(xì)節(jié)的部分沒(méi)有注意到,比如說(shuō),強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換,我自己編的時(shí)候沒(méi)有注意這個(gè)問(wèn)題,結(jié)果出了很多錯(cuò),有些事由于函數(shù)調(diào)用引起的,有些是由于不等號(hào)兩邊數(shù)據(jù)的匹配問(wèn)題,還有的是由于指針的移動(dòng),直到這個(gè)時(shí)候,才真正明白實(shí)驗(yàn)書(shū)上程序?yàn)槭裁茨敲炊鄰?qiáng)制類型轉(zhuǎn)換,雖然書(shū)上很多東西不是盡善盡美,但是對(duì)于我這種剛開(kāi)始學(xué)會(huì)編程的人還是有很多可以學(xué)習(xí)的地方的。
如老師所說(shuō),算法的效率是很重要的。要提高算法的效率,一個(gè)是要簡(jiǎn)化計(jì)算(不得不說(shuō),這需要數(shù)學(xué)基礎(chǔ)),另外一個(gè)就是要避免許多重復(fù)的計(jì)算。在參考書(shū)上的程序里,很多時(shí)候,為了避免這種重復(fù)的計(jì)算(在循環(huán)中表現(xiàn)尤其明顯),會(huì)把某些數(shù)當(dāng)常數(shù)算出來(lái),只要后來(lái)加上這個(gè)常數(shù)就可以,這樣,效率高很多。
另外,對(duì)許多出錯(cuò)的情況,我的程序里也沒(méi)有做好。比如,如果打開(kāi)的不是8位圖像,我的程序不會(huì)提示錯(cuò)誤,正常結(jié)束,而可能做錯(cuò),所以,這也是我應(yīng)該向別人程序?qū)W習(xí)的地方。
最后一個(gè),自己菜單的布局也是很亂的。要從一開(kāi)始就布局好。
【數(shù)字圖像處理實(shí)驗(yàn)報(bào)告】相關(guān)文章:
微污染水源處理實(shí)驗(yàn)報(bào)告06-02
初中物理實(shí)驗(yàn)報(bào)告-實(shí)驗(yàn)報(bào)告08-17
大學(xué)化學(xué)實(shí)驗(yàn)報(bào)告-實(shí)驗(yàn)報(bào)告08-16
有機(jī)化學(xué)實(shí)驗(yàn)報(bào)告-實(shí)驗(yàn)報(bào)告08-16