數字影象處理實驗報告

數字影象處理實驗報告

  一、數字影象處理的簡介

  數字影象處理(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點陣圖像,我的程式不會提示錯誤,正常結束,而可能做錯,所以,這也是我應該向別人程式學習的地方。

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

最近訪問