當前位置:文書都 >

知識文庫 >專業資料 >

數字圖像處理實驗報告

數字圖像處理實驗報告

一、數字圖像處理的簡介

數字圖像處理(Digital Image Processing)是通過計算機對圖像進行去除噪聲、增強、復原、分割、提取特徵等處理的方法和技術。數字圖像處理的產生和迅速發展主要受三個因素的影響:

一是計算機的發展;

二是數學的發展(特別是離散數學理論的創立和完善);

三是廣泛的農牧業、林業、環境、軍事、工業和醫學等方面的應用需求的增長。

數字圖像處理實驗報告

隨着個人素質的提升,需要使用報告的情況越來越多,通常情況下,報告的內容含量大、篇幅較長。你還在對寫報告感到一籌莫展嗎?以下是小編整理的數字圖像處理實驗報告,僅供參考,希望能夠幫助到大家。

數字圖像處理實驗報告1

一、實驗內容:

主要是圖像的幾何變換的編程實現,具體包括圖像的讀取、改寫,圖像平移,圖像的鏡像,圖像的轉置,比例縮放,旋轉變換等,具體要求如下:

1、編程實現圖像平移,要求平移後的圖像大小不變;

2、編程實現圖像的鏡像;

3、編程實現圖像的轉置;

4、編程實現圖像的比例縮放,要求分別用雙線性插值和最近鄰插值兩種方法來實現,並比較兩種方法的縮放效果;

5、編程實現以任意角度對圖像進行旋轉變換,要求分別用雙線性插值和最近鄰插值兩種方法來實現,並比較兩種方法的旋轉效果。

二、實驗目的和意義:

本實驗的目的是使學生熟悉並掌握圖像處理編程環境,掌握圖像平移、鏡像、轉置和旋轉等幾何變換的方法,並能通過程序設計實現圖像文件的讀、寫操作,及圖像平移、鏡像、轉置和旋轉等幾何變換的程序實現。

三、實驗原理與主要框架:

3.1實驗所用編程環境:

VisualC++(簡稱VC)是微軟公司提供的基於C/C++的應用程序集成開發工具、VC擁有豐富的功能和大量的擴展庫,使用它能有效的創建高性能的Windows應用程序和Web應用程序。

VC除了提供高效的C/C++編譯器外,還提供了大量的可重用類和組件,包括著名的微軟基礎類庫(MFC)和活動模板類庫(ATL),因此它是軟件開發人員不可多得的開發工具。

VC豐富的功能和大量的擴展庫,類的重用特性以及它對函數庫、DLL庫的支持能使程序更好的模塊化,並且通過嚮導程序大大簡化了庫資源的使用和應用程序的開發,正由於VC具有明顯的優勢,因而我選擇了它來作為數字圖像幾何變換的開發工具。

在本程序的開發過程中,VC的核心知識、消息映射機制、對話框控件編程等都得到了生動的體現和靈活的應用。

3.2實驗處理的對象:256色的BMP(BITMAP)格式圖像

BMP(BITMAP)位圖的文件結構:

具體組成圖:BITMAPFILEHEADER

位圖文件頭

(只用於BMP文件)bfType=”BM”bfSizebfReserved1

bfReserved2

bfOffBits

biSize

biWidth

biHeight

biPlanes

biBitCount

biCompression

biSizeImage

biXPelsPerMeter

biYPelsPerMeter

biClrUsed

biClrImportant

1、BMP文件組成

BMP文件由文件頭、位圖信息頭、顏色信息和圖形數據四部分組成。

2、BMP文件頭

BMP文件頭數據結構含有BMP文件的類型(必須為BMP)、文件大小(以字節為單位)、位圖文件保留字(必須為0)和位圖起始位置(以相對於位圖文件頭的偏移量表示)等信息。

3、位圖信息頭

BMP位圖信息頭數據用於説明位圖的尺寸(寬度,高度等都是以像素為單位,大小以字節為單位,水平和垂直分辨率以每米像素數為單位),目標設備的級別,每個像素所需的位數,位圖壓縮類型(必須是0)等信息。

4、顏色表

顏色表用於説明位圖中的顏色,它有若干個表項,每一個表項是一個RGBQUAD

類型的結構,定義一種顏色、具體包含藍色、紅色、綠色的亮度(值範圍為0-255)

位圖信息頭和顏色表組成位圖信息

5、位圖數據

位圖數據記錄了位圖的每一個像素值,記錄順序是在掃描行內是從左到右,掃描行之間是從下到上。

Windows規定一個掃描行所佔的字節數必須是4的倍數(即以long為單位),不足的以0填充。

3.3BMP(BITMAP)位圖的顯示:

①一般顯示方法:

1、申請內存空間用於存放位圖文件

2、位圖文件讀入所申請內存空間中

3、在函數中用創建顯示用位圖,用函數創建兼容DC,用函數選擇顯示刪除位圖

但以上方法的.缺點是:1)顯示速度慢;

2)內存佔用大;

3)位圖在縮小顯示時圖形失真大,(可通過安裝字體平滑軟件來解決);

4)在低顏色位數的設備上(如256顯示模式)顯示高顏色位數的圖形(如真彩色)圖形失真嚴重。

②BMP位圖縮放顯示:

用視頻函數來顯示位圖,內存佔用少,速度快,而且還可以對圖形進行淡化(Dithering)處理、淡化處理是一種圖形算法,可以用來在一個支持比圖像所用顏色要少的設備上顯示彩色圖像、BMP位圖顯示方法如下:

1、打開視頻函數,一般放在在構造函數中

2、申請內存空間用於存放位圖文件

3、位圖文件讀入所申請內存空間中

4、在函數中顯示位圖

5、關閉視頻函數,一般放在在析構函數中

以上方法的優點是:

1)顯示速度快;

2)內存佔用少;

3)縮放顯示時圖形失真小;

4)在低顏色位數的設備上顯示高顏色位數的圖形圖形時失真小;

5)通過直接處理位圖數據,可以製作簡單動畫。

3.4程序中用到的訪問函數

Windows支持一些重要的DIB訪問函數,但是這些函數都還沒有被封裝到MFC中,這些函數主要有:

1、SetDIBitsToDevice函數:該函數可以直接在顯示器或打印機上顯示DIB、在顯示時不進行縮放處理。

2、StretchDIBits函數:該函數可以縮放顯示DIB於顯示器和打印機上。

3、GetDIBits函數:還函數利用申請到的內存,由GDI位圖來構造DIB、通過該函數,

可以對DIB的格式進行控制,可以指定每個像素顏色的位數,而且可以指定是否進行壓縮。

4、CreateDIBitmap函數:利用該函數可以從DIB出發來創建GDI位圖。

5、CreateDIBSection函數:該函數能創建一種特殊的DIB,稱為DIB項,然後返回一個GDI位圖句柄。

6、LoadImage函數:該函數可以直接從磁盤文件中讀入一個位圖,並返回一個DIB句柄。

7、DrawDibDraw函數:Windows提供了窗口視頻(VFW)組件,VisualC++支持該組件、VFW中的DrawDibDraw函數是一個可以替代StretchDIBits的函數、它的最主要的優點是可以使用抖動顏色,並且提高顯示DIB的速度,缺點是必須將VFW代碼連接到進程中、

3.5圖像的幾何變換

圖像的幾何變換,通常包括圖像的平移、圖像的鏡像變換、圖像的轉置、圖像的縮放和圖像的旋轉等。

數字圖像處理實驗報告2

一、實驗的目的和意義

實驗目的:本實驗內容旨在讓學生通過用VC等高級語言編寫數字圖像處理的一些基本算法程序,來鞏固和掌握圖像處理技術的基本技能,提高實際動手能力,並通過實際編程瞭解圖像處理軟件的實現的基本原理。為學生進一步學習數字攝影測量、遙感和地理信息系統等專業課程以及應用圖像處理解決實際問題奠定基礎。

二、實驗原理和方法

(1)Raw格式到BMP格式的轉換:

Raw格式:Raw格式文件是按照數字圖像組成的二維矩陣,將像素按行列號順序存儲在文件中。這種文件只含有圖像像素數據,不含有信息頭,因此,在讀圖像時,需要根據文件大小,計算圖像所包含的行列號,或者需要事先知道圖像大小(矩陣大小)。RAW文件按圖像上行到下行、左列到右列順序存儲。

BMP格式:BMP文件數據區按圖像上下行到上行、左列列到右列順序存儲到數據區。BMP文件由文件頭、信息頭、顏色表、數據區四個部分組成。

做Raw格式文件到BMP格式文件的轉化,先要為BMP格式文件申請四部分的內存:文件頭,位圖信息頭,顏色表,圖象數據,然後根據輸入值以及Raw文件信息,BMP格式文件信息計算出這幾部分的值,賦給他們,寫到BMP文件中去。

(2)灰度圖象的線性拉伸:

灰度變化是點運算,將原圖象的每個像素的灰度值改成線性變化之後的灰度即可。

灰度的線性變換就是指圖像的中所有點的灰度按照線性灰度變換函數進行變換。灰度變換方程如下:

該方程為線性方程。式中參數為輸入圖像的像素的灰度值,參數為輸出圖像的灰度值。

設原圖象的灰度範圍為[a,b],變化之後的範圍為[a’,b’],則:

fA=(b’-a’)/(b-a)

fB=-(b’-a’)/(b-a)*a+a’

如果算出來的值大於255,則讓它等於255,小於0則讓其等於0。

(3)局部處理(3*3高通濾波,3*3低通濾波):

局部處理在處理某一像素時,利用與該像素相鄰的一組像素,經過某種變換得到處理後圖像中某一點的像素值。目標像素的鄰域一般是由像素組成的二維矩陣,該矩陣的大小為奇數,目標像素位於該矩陣的中央,即目標像素就是區域的中心像素。經過處理後,目標像素的值為經過特定算法計算後所得的結果。

實際上都是利用卷積來實現的,卷積往往用一個矩陣表示,將矩陣的中心對齊某個像素,矩陣中的值乘到相應的像素中去,然後將所有乘積加起來就得到中心像素的灰度值。邊界像素不做處理,仍為原來的灰度值。求出的像素灰度值若超過[0~255],則向離其最近的屬於該範圍的像素值靠攏。

(4)圖象幾何處理(圖象平移,圖象縮放):

對於圖像平移來説,若平移量是(tx,ty),像素在原圖像中的座標為(x0,y0),則變化後的座標為(x1,y1),x1=x0+tx,y1=y0+ty。平移只需改變像素的灰度值,不必改變位圖信息頭和調色板內容。

對於圖像縮放,假設放大因子為ratio,縮放的變換矩陣為:

圖像信息頭中新圖像的寬度和高度都變為原來寬度和高度分別與水平垂直比例的乘積,圖像大小變為新寬度(變為4的整數倍)與新高度的乘積。

(5)灰度圖象中值濾波:

中值濾波也屬於局部處理的一種,將窗口中的各個像素排序之後排序,取中值賦給模板中心的像素,所以窗口中個數一般是基數。

我用的中值濾波窗口是十字絲的9個數的窗口。

(6)灰度圖象邊緣檢測:

邊緣檢測有三種算子:Roberts,Prewit,Sobel。三種算子都是做一階差分的,通過算子算出各個像素的梯度值,將水平梯度的絕對值和垂直梯度的絕對值相加,若此梯度值大於某個閾值,則將其灰度值賦為255,否則賦為0。

(7)圖象旋轉:

圖像旋轉一般是以圖像中心為中心順時針旋轉,利用圖像的四個角點求出圖像旋轉後的大小。

先計算以圖像中心為原點座標系下原圖像四個角點的座標值,按照旋轉矩陣計算其旋轉之後的座標值,根據四個角點的新座標值計算出最大寬度和高度作為新圖像的寬度和高度值,按照計算值修改位圖信息頭,申請一塊新內存,存儲旋轉後圖像的灰度值。

旋轉矩陣如下:

同樣要求各個像素在原圖像中的座標,先將新圖像的座標系平移到圖像中心,做逆時針旋轉,然後再平移到屏幕左上角,然後將原圖像對應座標的值賦給新圖像。

(8)圖象二值化:

判斷分析法:假定圖像的灰度區間為[0,L-1],則選擇一閾值T將圖像的像素分為兩組。

為最大值所對應的T,就是所求判斷分析法的分割閾值。

搜尋到閾值之後,灰度值小於閾值的像素賦0,其他的賦1,修改文件信息頭,調色板,申請新內存。

(9)圖象直方圖:

統計各灰度值出現的頻數,以及像素的總個數,用頻數除以總個數作為頻率,以灰度值作為橫座標,頻率作為縱座標繪圖。

三、實驗過程和步驟

首先要建立一個基於MFC的多文檔工程,將視圖基類改為滾動視圖,以自己的學號命名。

我用的是書上給的CDib類,類裏面有獲取BMP寬度,高度的函數,有指向位圖信息頭的指針,指向圖象數據的指針,因此我在文檔類(Doc類)裏定義了一個CDib類的對象,打開以及保存文件的時候利用這個對象去調用CDib裏讀取與存儲文件的函數,並且可以利用這個對象的兩個指針對打開的圖象進行各種操作。

1、Raw格式到BMP格式的轉換:

首先建立一個RawToBMP的對話框,在上面加上四個編輯框(一個輸入打開文件的路徑一個輸入保存文件的路徑,另兩個),兩個按鈕,以及默認的確認,取消按鈕。利用類嚮導插入此對話框類,並且為前兩個編輯框定義CString的兩個變量,用來存儲打開與保存文件的路徑。同時為兩個瀏覽按鈕添加消息響應函數,在消息函數裏創建CFileDialog對象,利用此對象的函數將兩個路徑值賦給前兩個編輯框的成員變量。再為OK鍵添加消息響應函數,分別定義BMP格式文件前三部分數據變量,計算出各變量的值,並且利用一個CFile對象獲取Raw圖象的數據,利用另一個CFile對象將數據存儲到所輸入的路徑的文件中去,CFile對象的Read函數會自動創建一個文件。

然後在菜單上新建一個菜單,為菜單添加消息響應函數,在其消息響應函數裏創建RowToBMP對話框。這樣點擊菜單後就會彈出一個對話框,按確定鍵之後就可以讀取Raw文件並且存儲BMP文件,完成整個消息循環。

2、灰度圖象的線性拉伸:

創建一個對話框來輸入變化後的灰度值,為對話框的兩個編輯框定義成員變量,在文檔類中添加處理函數,按照對話框輸入值計算出fA與fB,做一個循環,將0到255的灰度值,計算出拉伸後的灰度值(超限情況特殊處理),存放在下標為此值的一個數組中,然後利用文檔類的中定義的CDib類的成員變量m_DIB,獲得當前打開的圖像指向圖像數據部分的指針m_DIB、m_pBits,在數組中查出每個像素變化後的灰度值,並將此值賦給指針m_pBits指向的內存。刷新視圖。

然後在菜單中加上線性拉伸的菜單,為該菜單的ID添加消息響應函數,在該函數中創建對話框,並調用文檔類線性拉伸的函數,將對話框的兩個成員變量傳給此函數。

3、局部處理:

在文檔類裏添加低通濾波和高通濾波的成員函數,在函數中使用m_DIB對象中指向圖像數據部分的指針m_pBits,首先申請一個新內存,將原來圖像的灰度值存儲起來,然後定義9個BYTE類型的指針,利用雙重嵌套循環,在循環中每次用這9個指針指向複製圖像對應模板中的9個數,然後按照模板中的數值計算出中心像素的灰度值,判斷是否超過範圍,如果超過範圍則做相應的處理,否則將此值直接賦給m_pBits中對應的中心像素。循環之後刷新視圖。

添加局部處理的菜單,為菜單設置消息響應函數,在菜單消息響應函數中調用文檔類的函數,完成對m_DIB的處理。

4、圖像幾何變換:

建立平移對話框,定義兩個成員變量,分別存儲輸入的水平位移和垂直位移。

在文檔類裏添加平移函數,申請一塊新內存複製原圖像的信息,在函數中將外層循環變量i視為縱座標,內層循環變量j視為橫座標,通過雙重循環,對每個像素,求出其在原圖像中的座標(i0,j0),將複製圖像中的對應(i0,j0)的像素灰度值賦給m_DIB、m_pBits指針中的圖像。如果在原圖像中找不到該像素,置為背景色。刷新視圖。

在菜單中添加圖像平移菜單,併為該菜單添加消息響應函數,在此函數中創建平移對話框,調用文檔類的平移函數,將對話框的成員變量傳入該函數。

建立縮放對話框類,為此類定義兩個成員變量,存儲輸入的水平縮放因子和垂直縮放因子。

再在文檔類中添加縮放函數,利用m_DIB、m_pBMI(指向位圖信息頭的指針),修改位圖信息頭中的寬度,高度,圖像大小。計算出新圖像的大小,申請一塊新內存存儲新圖像,同平移函數一樣,計算出每個像素在原圖像中的座標,i0=i/PRatio,j0=j/VRatio,PRatio與VRatio分別為水平縮放因子和垂直縮放因子。將原圖像中對應座標的灰度值賦給新內存,然後將m_DIB、m_pBits(指向圖像數據的指針)指向新內存,刷新視圖。

5、中值濾波:

在文檔類中添加兩個成員函數。一個用來把傳入的指針裏的內容排序,一個用來做中值濾波。也要申請一塊新內存來複制原圖像的信息,雙重嵌套循環,邊界像素不處理,對每個像素,使用一個大小為9個字節的數組來存放複製圖像窗口中各像素值,然後將數組首地址傳入排序的函數中,將中間的值賦給當前圖像窗口中心的像素。排序函數我用的是快速排序法。

在菜單中添加中值濾波菜單項,為其添加消息響應函數,調用文檔類的中值濾波函數。

6、邊緣檢測:

在文檔類中定義三個函數,分別為Roberts,Prewit,Sobel算子處理函數,處理時,先申請新內存複製原來圖像信息,邊界像素不作處理,對每個像素值,求出其在複製圖像中的梯度,判斷,若梯度值大於150(這個是我自己定的),則將灰度值賦為255,否則置零。

菜單中添加邊緣檢測菜單,置屬性為Pop—up,添加三個下一級菜單,分別為Roberts,Prewit,Sobel,各個菜單的消息響應函數中調用文檔類中各自的處理函數。

7、圖像旋轉:

創建一個對話框輸入旋轉角度,在文檔類中添加成員函數。

先將角度化為弧度值。

計算原圖像四個角點的座標,以及新圖像四個角點的座標。

根據新圖像四個角點的座標,取對角線上兩個點橫座標差值較大值作為寬度,縱座標差值較大值作為高度。

根據計算出來的高度和寬度修改文件信息頭,並且申請內存存儲新圖像。

計算每點的像素在原來圖像中的座標從而獲取其灰度值,寫入新內存。

將m_DIB、m_pBits指向該新內存。刷新視圖。

添加圖像旋轉菜單,在菜單響應函數中創建對話框,調用文檔類中旋轉函數,將對話框中獲取的角度傳給旋轉函數。

8、圖像二值化:

在文檔類添加一個成員函數,根據傳人的圖像和閾值返回組間方差和組內方差的比值。

再添加一個成員函數,進行二值化。

在函數中:

計算新BMP文件的大小,申請一塊新內存,存儲新的整個BMP文件的信息,將位圖信息頭中biBitCount置為1,調色板數組只有兩個兩個元素,下標為0的三個灰度值都為0,下標為1的三個灰度值為255。

從最大灰度值到最小灰度值之間搜尋上述函數返回值最大的值,作為閾值。

對每個像素,若其原來灰度值小於閾值,賦1,否則賦0。

將m_DIB,m_pBits指向新內存的圖像數據部分,m_DIB、m_pBMI指向位圖信息頭。

9、圖像直方圖:

為文檔類添加一個int型指針成員變量m_pGray,在構造函數中將該指針賦空,在文檔類中定義了一個函數,統計各個灰度值出現的頻數,申請一個內存,存儲在這個內存中,並將m_pGray指向它。

創建一個畫直方圖的對話框,添加Picture控件,在控件裏調用文檔類成員變量,畫直方圖。添加一個滾動條,用來確定閾值,為滾動條添加消息響應函數,按照滾動條的值進行二值化。

在菜單中添加直方圖菜單,添加消息響應函數,在響應函數中創建直方圖對話框對象。

最後,因為我開始做工程的時候沒有把菜單設計好,做得有點亂,所以,我又在View裏添加WM_CONTEXTMENU消息響應函數,在函數體內用CMenu類來實現彈出菜單。

四、實驗總結與體會

這次實驗學到最大的東西,是自己總算有MFC編程的概念了,雖然自己VC++考試的分數還不錯,但是裏面的很多東西,不通過自己的編程時絕對不能真正理解。比如説封裝性,這次用CDib的方便,很好地利用了類的封裝性。另外,比如MFC是基於消息響應機制的,這就決定了,要利用鼠標或者菜單響應函數去實現功能,而用c語言編寫程序的時候,完全是按主函數的線程來的。

另外,我也學會了調試的真正含義。以前都只知道那幾個按鍵是做什麼用的,調試的真正目的,是根據自己的算法來檢驗程序計算的各個值是否符合,從而可以很快速方便地查到自己的錯誤。

自學也是很重要的一方面。實際上,在現在來説,用MSDN也不是很難的事了,我們不應該被英文打到,而且現在,隨着對一些專有名詞熟悉了之後,看MSDN也容易一些了,萬一不懂的函數,也可以利用網絡查到很多函數功能用法的解釋。

剛開始的時候做的是位圖的讀取和顯示,實在是不知從哪裏做起,所以就照着實驗書上敲了前面的部分,但是慢慢地也看懂了代碼的意思。所以後來的基本上都是自己做的了,但是算法還是基本上和書上差不多。不過自己編的時候還是有很多細節的部分沒有注意到,比如説,強制數據類型轉換,我自己編的時候沒有注意這個問題,結果出了很多錯,有些事由於函數調用引起的,有些是由於不等號兩邊數據的匹配問題,還有的是由於指針的移動,直到這個時候,才真正明白實驗書上程序為什麼那麼多強制類型轉換,雖然書上很多東西不是盡善盡美,但是對於我這種剛開始學會編程的人還是有很多可以學習的地方的。

如老師所説,算法的效率是很重要的。要提高算法的效率,一個是要簡化計算(不得不説,這需要數學基礎),另外一個就是要避免許多重複的計算。在參考書上的程序裏,很多時候,為了避免這種重複的計算(在循環中表現尤其明顯),會把某些數當常數算出來,只要後來加上這個常數就可以,這樣,效率高很多。

另外,對許多出錯的情況,我的程序裏也沒有做好。比如,如果打開的不是8位圖像,我的程序不會提示錯誤,正常結束,而可能做錯,所以,這也是我應該向別人程序學習的地方。

最後一個,自己菜單的佈局也是很亂的。要從一開始就佈局好。

  • 文章版權屬於文章作者所有,轉載請註明 https://wenshudu.com/zhishiwenku/zhuanyeziliao/2z8dx.html
專題