QT图像处理-_第1页
QT图像处理-_第2页
QT图像处理-_第3页
QT图像处理-_第4页
QT图像处理-_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、QT 实现图像处理 -傅立叶变换、傅立叶反变换、平滑、锐化与模板匹配实验环境:1, Linux 操作系统2, QT3 编程开发环境3,C+ 编程语言傅立叶变换和傅立叶反变换1.1. 主要源代码readImage() 从图像中读取数据 writeImage() 往图像中写入数据 fft() 快速傅立叶变换 ifft() 快速傅立叶反变换 adjustImageSize() 调整图像大小 fourier() 傅立叶变换 ifourier() 傅立叶反变换1.1.1 从图像中读取数据void ImageProcess:readImage(complex data, const QImage &src

2、Image)byte *pImageBytes = srcImage.bits(); /数据首地址int depth = srcImage.depth(); / 每个像素的 bit 数int lineBytes = srcImage.bytesPerLine(); /每行的字节数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+)if(8 = depth) / 采用了 256 色

3、调色板, 8位颜色索引pByte = pImageBytes + i * lineBytes + j;datai * w + j = complex( *pByte, 0);else if(32 = depth)/32 位表示,数据格式为 0xFFBBGGRR 或 0xAABBGGRRpByte = pImageBytes + i * lineBytes + j * 4;/ 根据 RGB 模式转化成 YIQ 色彩模式的方式,取 Y 作为灰度值byte pixelValue = (byte)(0.299 * (float)pByte0 + 0.587 * (float)pByte1+ 0.114

4、 * (float)pByte2);datai * w + j = complex( pixelValue, 0);elsecout invalid format. depth = depth n;return;1.1.2 将数据写入图像/coef 为比例系数,主要用来调整灰度值以便于观察void ImageProcess:writeImage(QImage &destImage, const complex data, double coef)int lineBytes = destImage.bytesPerLine();int depth = destImage.depth();int

5、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 255 ? 255 : spectral;/根据图像格式写数据if(8 = depth)pByte = pImageBytes + i * lineBytes + j;*pByte = spectral;else if(32 = depth)pByte = pImageBytes + i * lineBytes + j *

6、 4;pByte0 = pByte1 = pByte2 = spectral;elsereturn;1.1.3 递归形式的快速傅立叶变换/ 数组 a 为输入,数组 y 为输出, 2 的 power 次方为数组的长度void ImageProcess:fft(const complex a, complex y, int power) if(0 = power)y0 = a0;return;int n = 1 power;double angle = 2 * PI / n;complex wn(cos(angle), sin(angle);complex w(1, 0);complex *a0

7、= new complexn / 2;complex *a1 = new complexn / 2;complex *y0 = new complexn / 2;complex *y1 = new complexn / 2;for(int i = 0; i n / 2; i +)a0i = a2 * i;a1i = a2 * i + 1;/ 分开成两个子 fft 过程 fft(a0, y0, power - 1); fft(a1, y1, power - 1); complex u;for(int k = 0; k n / 2; k+) / 蝶形算法u = w * y1k;yk = y0k +

8、 u;yk + n / 2 = y0k - u;w = w * wn;delete a0;delete a1;delete y0;delete y1;1.1.4 快速傅立叶反变换/y 为输入, a 为输出, 2 的 power 次方为数组的长度void ImageProcess:ifft(const complex y, complex a, int power) int count = 1 power; complex *x = new complexcount; memcpy(x, y, sizeof(complex) * count);int i;for(i = 0; i count;

9、i+)xi = complex(xi.real(), -xi.imag(); / 共轭复数fft(x, a, power); / 调用快速傅立叶变换算法for(i = 0; i count; i+)ai = complex(ai.real() / count, -ai.imag() / count); /共轭复数delete x;1.1.5 调整图像的大小/ 宽和高都截取为 2 的指数倍void ImageProcess:adjustImageSize(QImage &image)int w = 1;int h = 1;int width = image.width();int height

10、= image.height();wp = 0, hp = 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 bytesPerPix

11、el = image.depth() / 8; / 每个象素的字节数for(int i = 0; i h; i+) / 拷贝数据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(n

12、eedAdjust) / 调整图像的大小为 2 的幂次以便于快速傅立叶变换 adjustImageSize(currentImage); / 调整大小 needAdjust = false;if(currentImageData)delete currentImageData; currentImageData = new complexw * h;readImage(currentImageData, currentImage); /读取数据else if(NULL = currentImageData) currentImageData = new complexw * h; readIm

13、age(currentImageData, currentImage); /读取数据w = currentImage.width(); / 更新宽和高h = currentImage.height();complex *TD = currentImageData; / 当前读取的数据为时域 complex *FD = new complexw * h; /申请空间保存变换结果int i, j;for(i = 0; i h; i+) / 在 x 方向上对按行进行快速傅立叶变换fft(&TDw * i, &FDw * i, wp);memcpy(TD, FD, sizeof(complex) *

14、w * h); complex *columnt = new complexh; complex *columnf = new complexh;for(i = 0; i w; i+) / 调整行列数据,在 y 方向上按列进行快速傅立叶变换 for(j = 0; j h; j+)columntj = TDj * w + i;fft(columnt, columnf, hp);for(j = 0; j setPixmap(QPixmap(curre ntlmage);1.1.7傅立叶反变换傅立叶反变换的思想与傅立叶变化相似,只是时域和频域互换,然后调用快速傅立叶反变换ifft而不是快速傅立叶变换

15、fft o1.2.运行截图1.2.1正方形输入一个256*256的图形,背景为白色,中间有一黑色的正方形,如图1-1所示。经过傅立叶变换后的结果如图1-2所示(注:没有采用平移到中心的方法)。图1-1图1-21.2.2旋转45度将图1-1旋转45度后的输入如图1-3所示。其傅立叶变换结果如图1-4所示。图1-3图1-41.2.3输入长方形图像输入图像如图1-5所示。傅立叶变换结果如图1-6所示。图1-5图1-61.2.4傅立叶反变换对傅立叶变换结果图1-2进行傅立叶反变换,其结果与原图1-1相同,如图1-7所示:图1-7图像增强图像增强是一种很重要的图像处理技术,为了方便人们观察以及机器处理而

16、去处理给定的一幅图像。有很多图像增强的方法,以下这部分实现了其中的平滑和锐化这两种方法。2.1.主要源码2.1.1平滑_i 1 rliii9平滑采用的模板是卩1 1,实现如下:void lmageProcess:smooth()int w = curre ntlmage.width();int h = curre ntlmage.height();if(NULL = curren tlmageData) /判断是否需要重新读取数据curre ntlmageData = new complexw * h;readlmage(curre ntlmageData, curre ntlmage);/拷

17、贝一份数据便于计算complex *buffer = new complexw * h;memcpy(buffer, curre ntlmageData, sizeof(complex) * w * h);/根据模板进行计算/为了简化编码忽略了图像边界(i =0 or h, j =0 or w),对于整体效果没有影响int i, j;for(i = 1; i h - 1; i+)for(j = 1; j w - 1; j+)complex k;k = buffer(i - 1) * w + j - 1;k += buffer(i - 1) * w + j;k += buffer(i - 1)

18、* 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) * w + j + 1;k = complex(k.real() / 9, 0);curre ntlmageDatai * w + j = k;writelmage(currentlmage, currentlmageData);pDispLabel-setPixmap(QPix

19、map(curre ntlmage);2.1.2锐化0-10_-15-1采用拉普拉斯锐化,其模板为0-10_,其实现如下void ImageProcess:sharp()int w = currentImage.width();int h = currentImage.height();if(NULL = currentImageData) / 判断是否需要读取数据currentImageData = new complexw * h; readImage(currentImageData, currentImage);/拷贝一份数据便于计算 complex *buffer = new com

20、plexw * h;memcpy(buffer, currentImageData, sizeof(complex) * w * h); /根据模板进行计算/ 为了简化编码忽略了图像边界 (i =0 or h, j =0 or w) ,对于整体效果没有影响 int i, j;complex k;for(i = 1; i h - 1; i+)for(j = 1; j w - 1; j+)k = bufferi * w + j;k = complex(k.real() * 5, 0);k -= buffer(i - 1) * w + j;k -= bufferi * w + j - 1;k -=

21、bufferi * w + j + 1;k -= buffer(i + 1) * w + 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锐化后的图像图像分析这部分主要实现了图像的模板匹配。 模板匹配是一种非常原始的模式识别方法。 有很多模板 匹配的算法。这里采用的算法是

22、计算二者之间的相似度, 在目标图像中选取一个坐标, 将以 该坐标为左上角选定一块区域, 计算该区域与模板的相似度, 相似度最大的点即为匹配之处。通过二者之间的差异度来判断其相似程度,差异度的计算:m=:。即将累加其像m 大于阀值时,认定该块区域不匹素之间的差值,为了提高计算速度,可以设置阀值,当 配,继续寻找下一区域。3.1. 主要源码 void ImageProcess:match() /让用户选取模板QString fileName = QFileDialog:getOpenFileName(/home/tanqiyu, Images (*.png *.xpm.jpg), this, op

23、en file dialog, Choose a model image); if(QString:null = fileName) return;/读取模板数据QImage modelImage(fileName);int mw = modelImage.width();int mh = modelImage.height(); complex *modelImageData = new complexmw * mh; readImage(modelImageData, modelImage);unsigned long t = mw * mh * 8; / 根据匹配模板的大小设置一定的阀值 unsigned long m = t; / 初始差异度 int ri = -1; /z 左上角坐标 (ri, rj)int rj = -1;int w = currentImage.width();int h = currentImage.heig

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论