QT實現(xiàn)圖像處理-傅立葉變換傅立葉反變換平滑銳化與模板匹配_第1頁
QT實現(xiàn)圖像處理-傅立葉變換傅立葉反變換平滑銳化與模板匹配_第2頁
QT實現(xiàn)圖像處理-傅立葉變換傅立葉反變換平滑銳化與模板匹配_第3頁
QT實現(xiàn)圖像處理-傅立葉變換傅立葉反變換平滑銳化與模板匹配_第4頁
QT實現(xiàn)圖像處理-傅立葉變換傅立葉反變換平滑銳化與模板匹配_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、QT實現(xiàn)圖像處理-傅立葉變換、傅立葉反變換、平滑、銳化與模板匹配 實驗環(huán)境:1,Linux操作系統(tǒng)2,QT3編程開發(fā)環(huán)境3,C+編程語言傅立葉變換和傅立葉反變換1.1. 主要源代碼readImage() 從圖像中讀取數(shù)據(jù)writeImage() 往圖像中寫入數(shù)據(jù)fft() 快速傅立葉變換ifft() 快速傅立葉反變換adjustImageSize() 調整圖像大小fourier() 傅立葉變換ifourier() 傅立葉反變換 1.1.1 從圖像中讀取數(shù)據(jù) void ImageProcess:readImage(complex<double> data, const QImage

2、&srcImage) byte *pImageBytes = srcImage.bits(); /數(shù)據(jù)首地址 int depth = srcImage.depth(); /每個像素的bit數(shù) int lineBytes = srcImage.bytesPerLine(); /每行的字節(jié)數(shù) int w = srcImage.width(); /寬 int h = srcImage.height(); /高 byte *pByte; /遍歷讀取每個像素,并轉換為灰度值 int i, j; for(i = 0; i < h; i+) for(j = 0; j < w; j+) i

3、f(8 = depth) /采用了256色調色板,8位顏色索引 pByte = pImageBytes + i * lineBytes + j; datai * w + j = complex<double>( *pByte, 0); else if(32 = depth)/32位表示,數(shù)據(jù)格式為0xFFBBGGRR或0xAABBGGRR pByte = pImageBytes + i * lineBytes + j * 4; /根據(jù)RGB模式轉化成YIQ色彩模式的方式,取Y作為灰度值 byte pixelValue = (byte)(0.299 * (float)pByte0 +

4、 0.587 * (float)pByte1 + 0.114 * (float)pByte2); datai * w + j = complex<double>( pixelValue, 0); else cout << "invalid format. depth = " << depth << "n" return; 1.1.2 將數(shù)據(jù)寫入圖像 /coef為比例系數(shù),主要用來調整灰度值以便于觀察 void ImageProcess:writeImage(QImage &destImage, co

5、nst complex<double> data, double coef) int lineBytes = destImage.bytesPerLine(); int depth = destImage.depth(); int w = destImage.width(); int h = destImage.height(); byte *pImageBytes = destImage.bits(); byte *pByte; for(int i = 0; i < h; i+) for(int j = 0; j < w; j+) double spectral =

6、abs(datai * w + j) * coef; /灰度值調整 spectral = spectral > 255 ? 255 : spectral; /根據(jù)圖像格式寫數(shù)據(jù) if(8 = depth) pByte = pImageBytes + i * lineBytes + j; *pByte = spectral; else if(32 = depth) pByte = pImageBytes + i * lineBytes + j * 4; pByte0 = pByte1 = pByte2 = spectral; else return; 1.1.3 遞歸形式的快速傅立葉變換

7、/數(shù)組a為輸入,數(shù)組y為輸出,2的power次方為數(shù)組的長度 void ImageProcess:fft(const complex<double> a, complex<double> y, int power) if(0 = power) y0 = a0; return; int n = 1 << power; double angle = 2 * PI / n; complex<double> wn(cos(angle), sin(angle); complex<double> w(1, 0); complex<doubl

8、e> *a0 = new complex<double>n / 2; complex<double> *a1 = new complex<double>n / 2; complex<double> *y0 = new complex<double>n / 2; complex<double> *y1 = new complex<double>n / 2; for(int i = 0; i < n / 2; i +) a0i = a2 * i; a1i = a2 * i + 1; /分開成兩個子fft

9、過程 fft(a0, y0, power - 1); fft(a1, y1, power - 1); complex<double> u; for(int k = 0; k < n / 2; k+) /蝶形算法 u = w * y1k; yk = y0k + u; yk + n / 2 = y0k - u; w = w * wn; delete a0; delete a1; delete y0; delete y1; 1.1.4 快速傅立葉反變換 /y為輸入,a為輸出,2的power次方為數(shù)組的長度 void ImageProcess:ifft(const complex&l

10、t;double> y, complex<double> a, int power) int count = 1 << power; complex<double> *x = new complex<double>count; memcpy(x, y, sizeof(complex<double>) * count); int i; for(i = 0; i < count; i+) xi = complex<double>(xi.real(), -xi.imag(); /共軛復數(shù) fft(x, a, powe

11、r); /調用快速傅立葉變換算法 for(i = 0; i < count; i+) ai = complex<double>(ai.real() / count, -ai.imag() / count); /共軛復數(shù) delete x; 1.1.5 調整圖像的大小 /寬和高都截取為2的指數(shù)倍 void ImageProcess:adjustImageSize(QImage &image) int w = 1; int h = 1; int width = image.width(); int height = image.height(); wp = 0, hp =

12、 0; while(w * 2 <= width) w *= 2; wp+; while(h * 2 <= height) h *= 2; hp+; QImage adjustedImage(w, h, image.depth(), image.numColors(), image.bitOrder(); byte *destBytes = adjustedImage.bits(); byte *srcBytes = image.bits(); int lineBytes = image.bytesPerLine(); int bytesPerPixel = image.depth

13、() / 8; /每個象素的字節(jié)數(shù) for(int i = 0; i < h; i+) /拷貝數(shù)據(jù) memcpy(destBytes + i * w * bytesPerPixel, srcBytes + i * lineBytes, sizeof(byte) * w * bytesPerPixel); image = adjustedImage; /更新圖像 1.1.6 傅立葉變換的主過程 void ImageProcess:fourier() int w = currentImage.width(); int h = currentImage.height(); if(needAdj

14、ust) /調整圖像的大小為2的冪次以便于快速傅立葉變換 adjustImageSize(currentImage); /調整大小 needAdjust = false; if(currentImageData) delete currentImageData; currentImageData = new complex<double>w * h; readImage(currentImageData, currentImage); /讀取數(shù)據(jù) else if(NULL = currentImageData) currentImageData = new complex<d

15、ouble>w * h; readImage(currentImageData, currentImage); /讀取數(shù)據(jù) w = currentImage.width(); /更新寬和高 h = currentImage.height(); complex<double> *TD = currentImageData; /當前讀取的數(shù)據(jù)為時域 complex<double> *FD = new complex<double>w * h; /申請空間保存變換結果 int i, j; for(i = 0; i < h; i+) /在x方向上對按行進

16、行快速傅立葉變換 fft(&TDw * i, &FDw * i, wp); memcpy(TD, FD, sizeof(complex<double>) * w * h); complex<double> *columnt = new complex<double>h; complex<double> *columnf = new complex<double>h; for(i = 0; i < w; i+) /調整行列數(shù)據(jù),在y方向上按列進行快速傅立葉變換 for(j = 0; j < h; j+) co

17、lumntj = TDj * w + i; fft(columnt, columnf, hp); for(j = 0; j < h; j+) FDj * w + i = columnfj; delete columnt; delete columnf; writeImage(currentImage, FD, 0.02); /寫入數(shù)據(jù) delete currentImageData; currentImageData = FD; pDispLabel->setPixmap(QPixmap(currentImage); 1.1.7 傅立葉反變換 傅立葉反變換的思想與傅立葉變化相似,只

18、是時域和頻域互換,然后調用快速傅立葉反變換ifft而不是快速傅立葉變換fft。 1.2. 運行截圖1.2.1 正方形 輸入一個256*256的圖形,背景為白色,中間有一黑色的正方形,如圖1-1所示。經(jīng)過傅立葉變換后的結果如圖1-2所示(注:沒有采用平移到中心的方法)。 圖1-1 圖1-2 1.2.2 旋轉45度 將圖1-1旋轉45度后的輸入如圖1-3所示。其傅立葉變換結果如圖1-4所示。 圖1-3 圖1-4 1.2.3 輸入長方形圖像 輸入圖像如圖1-5所示。傅立葉變換結果如圖1-6所示。 圖1-5 圖1-6 1.2.4 傅立葉反變換 對傅立葉變換結果圖1-2進行傅立葉反變換,其結果與原圖1-

19、1相同,如圖1-7所示: 圖1-7 圖像增強圖像增強是一種很重要的圖像處理技術,為了方便人們觀察以及機器處理而去處理給定的一幅圖像。有很多圖像增強的方法,以下這部分實現(xiàn)了其中的平滑和銳化這兩種方法。 2.1. 主要源碼2.1.1 平滑 平滑采用的模板是, 實現(xiàn)如下: void ImageProcess:smooth() int w = currentImage.width(); int h = currentImage.height(); if(NULL = currentImageData) /判斷是否需要重新讀取數(shù)據(jù) currentImageData = new complex<do

20、uble>w * h; readImage(currentImageData, currentImage); /拷貝一份數(shù)據(jù)便于計算 complex<double> *buffer = new complex<double>w * h; memcpy(buffer, currentImageData, sizeof(complex<double>) * w * h); /根據(jù)模板進行計算 /為了簡化編碼忽略了圖像邊界(i =0 or h, j =0 or w),對于整體效果沒有影響 int i, j; for(i = 1; i < h - 1;

21、i+) for(j = 1; j < w - 1; j+) complex<double> k; k = buffer(i - 1) * w + j - 1; k += buffer(i - 1) * w + j; k += buffer(i - 1) * w + j + 1; k += bufferi * w + j - 1; k += bufferi * w + j; k += bufferi * w + j + 1; k += buffer(i + 1) * w + j - 1; k += buffer(i + 1) * w + j; k += buffer(i + 1

22、) * w + j + 1; k = complex<double>(k.real() / 9, 0); currentImageDatai * w + j = k; writeImage(currentImage, currentImageData); pDispLabel->setPixmap(QPixmap(currentImage); 2.1.2 銳化 采用拉普拉斯銳化,其模板為,其實現(xiàn)如下: void ImageProcess:sharp() int w = currentImage.width(); int h = currentImage.height(); i

23、f(NULL = currentImageData) /判斷是否需要讀取數(shù)據(jù) currentImageData = new complex<double>w * h; readImage(currentImageData, currentImage); /拷貝一份數(shù)據(jù)便于計算 complex<double> *buffer = new complex<double>w * h; memcpy(buffer, currentImageData, sizeof(complex<double>) * w * h); /根據(jù)模板進行計算 /為了簡化編碼忽

24、略了圖像邊界(i =0 or h, j =0 or w),對于整體效果沒有影響 int i, j; complex<double> k; for(i = 1; i < h - 1; i+) for(j = 1; j < w - 1; j+) k = bufferi * w + j; k = complex<double>(k.real() * 5, 0); k -= buffer(i - 1) * w + j; k -= bufferi * w + j - 1; k -= bufferi * w + j + 1; k -= buffer(i + 1) * w

25、 + j; currentImageDatai * w + j = k; writeImage(currentImage, currentImageData); pDispLabel->setPixmap(QPixmap(currentImage); 2.2. 運行截圖輸入圖像2-1,其平滑結果為圖2-2,銳化結果為 圖2-3。 圖2-1原來的圖像 圖2-2 平滑后的圖像 圖2-3 銳化后的圖像 圖像分析這部分主要實現(xiàn)了圖像的模板匹配。模板匹配是一種非常原始的模式識別方法。有很多模板匹配的算法。這里采用的算法是計算二者之間的相似度,在目標圖像中選取一個坐標,將以該坐標為左上角選定一塊區(qū)域

26、,計算該區(qū)域與模板的相似度,相似度最大的點即為匹配之處。通過二者之間的差異度來判斷其相似程度,差異度的計算:m = 。即將累加其像素之間的差值,為了提高計算速度,可以設置閥值,當m大于閥值時,認定該塊區(qū)域不匹配,繼續(xù)尋找下一區(qū)域。 3.1. 主要源碼void ImageProcess:match() /讓用戶選取模板 QString fileName = QFileDialog:getOpenFileName("/home/tanqiyu", "Images (*.png *.xpm .jpg)", this, "open file dialo

27、g", "Choose a model image"); if(QString:null = fileName) return; /讀取模板數(shù)據(jù) QImage modelImage(fileName); int mw = modelImage.width(); int mh = modelImage.height(); complex<double> *modelImageData = new complex<double>mw * mh; readImage(modelImageData, modelImage); unsigned long t = mw * mh * 8; /根據(jù)匹配模板的大小設置一定的閥值 unsigned long m = t; /初始差異度 int ri = -1; /z左上角坐標(ri, rj) int rj = -1; int w = currentImage.width(); int h = currentImage.height(); if(NULL = currentImageData) /判斷是否需要讀取目標圖像數(shù)據(jù) currentImageData = new complex<double>w * h; readI

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論