数字图像处理_第1页
数字图像处理_第2页
数字图像处理_第3页
数字图像处理_第4页
数字图像处理_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

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

文档简介

数字图像处理论文 学生姓名: 学号: 学院:信息学部 专业:计算机技术2016年11月

前言本论文的编写围绕四个工程:图像空域/时域变换、图像增强、染色体计数与提取Mnist链码组成。工程的编写基于Windows7操作系统,使用VS2013作为开发环境,以OpenCV作为内部核心处理算法库。工程的最终组成结构为:在此,我们不再说明OpenCV的配置环境的搭建,而是直接展示工程的核心代码以及所使用到的知识。

题目一将宽为2n的正方形图像,用FFT算法从空域变换到频域,并用频域图像的模来进行显示。使图像能量中心,对应到几何中心,并用频域图像的模来进行显示。将频域图象,通过FFT逆变换到空域,并显示。解决方案:我们在一个工程中完成以上三个步骤。#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>#include<iostream>usingnamespacecv;usingnamespacestd;intmain(){//以灰度模式读取原始图像并显示MatsrcImage=imread("lena.png",0);if(srcImage.empty()){cout<<"翻开图像失败!"<<endl;return-1;}imshow("原始图像",srcImage);//将输入图像延扩到最正确的尺寸,边界用0补充intm=getOptimalDFTSize(srcImage.rows);intn=getOptimalDFTSize(srcImage.cols);//将添加的像素初始化为0.Matpadded;copyMakeBorder(srcImage,padded,0,m-srcImage.rows,0,n-srcImage.cols,BORDER_CONSTANT,Scalar::all(0));//为傅立叶变换的结果(实部和虚部)分配存储空间。//将planes数组组合合并成一个多通道的数组complexIMatplanes[]={Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)};MatcomplexI;merge(planes,2,complexI);//进行就地离散傅里叶变换dft(complexI,complexI);//将复数转换为幅值,即=>log(1+sqrt(Re(DFT(I))^2+Im(DFT(I))^2))split(complexI,planes);//将多通道数组complexI别离成几个单通道数组,planes[0]=Re(DFT(I),planes[1]=Im(DFT(I))magnitude(planes[0],planes[1],planes[0]);//planes[0]=magnitudeMatmagnitudeImage=planes[0];//进行对数尺度(logarithmicscale)缩放magnitudeImage+=Scalar::all(1);log(magnitudeImage,magnitudeImage);//求自然对数//剪切和重分布幅度图象限//假设有奇数行或奇数列,进行频谱裁剪magnitudeImage=magnitudeImage(Rect(0,0,magnitudeImage.cols&-2,magnitudeImage.rows&-2));//重新排列傅立叶图像中的象限,使得原点位于图像中心intcx=magnitudeImage.cols/2;intcy=magnitudeImage.rows/2;Matq0(magnitudeImage,Rect(0,0,cx,cy));//ROI区域的左上Matq1(magnitudeImage,Rect(cx,0,cx,cy));//ROI区域的右上Matq2(magnitudeImage,Rect(0,cy,cx,cy));//ROI区域的左下Matq3(magnitudeImage,Rect(cx,cy,cx,cy));//ROI区域的右下//交换象限〔左上与右下进行交换〕Mattmp;q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);//交换象限〔右上与左下进行交换〕q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式normalize(magnitudeImage,magnitudeImage,0,1,CV_MINMAX);//显示效果图imshow("频域",magnitudeImage);//〔3〕频域-->空域Matinversed;dft(complexI,inversed,DFT_INVERSE|DFT_REAL_OUTPUT);normalize(inversed,inversed,0,1,CV_MINMAX);imshow("空域",inversed);waitKey();return0;}效果图:

题目二对于下面这幅图像,请问可以通过那些图像增强的手段,到达改善视觉效果的目的?请显示处理结果,并附简要处理流程说明。该图像存在的主要问题:存在椒盐噪声曝光不够导致光线昏暗解决方案:采用中值滤波去噪增加亮度,调整比照度详细代码:#include<opencv2/opencv.hpp>#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>#include<iostream>usingnamespacestd;usingnamespacecv;intContrastValue;//比照度值intBrightValue;//亮度值Matsrc,dst;//改变图像比照度和亮度值的回调函数staticvoidContrastAndBright(int,void*){//创立窗口namedWindow("【原始图窗口】",WINDOW_AUTOSIZE);//更改图像亮度与比照度for(inty=0;y<src.rows;y++){for(intx=0;x<src.cols;x++){for(intc=0;c<3;c++){dst.at<Vec3b>(y,x)[c]=saturate_cast<uchar>((ContrastValue*0.01)*(src.at<Vec3b>(y,x)[c])+BrightValue);}}}//显示图像imshow("【原始图窗口】",src);imshow("【效果图窗口】",dst);}intmain(intargc,char*argv[]){//翻开图像src=imread("two.png");if(src.empty()){cout<<"翻开图像失败!"<<endl;return-1;}//中值滤波去噪medianBlur(src,src,Size(5,5));dst=Mat::zeros(src.size(),src.type());//设定比照度和亮度的初值ContrastValue=80;BrightValue=80;//创立窗口namedWindow("【效果图窗口】",WINDOW_AUTOSIZE);//创立轨迹条createTrackbar("比照度:","【效果图窗口】",&ContrastValue,300,ContrastAndBright);createTrackbar("亮度:","【效果图窗口】",&BrightValue,200,ContrastAndBright);//调用回调函数ContrastAndBright(ContrastValue,0);ContrastAndBright(BrightValue,0);//等待用户按键,起到暂停的作用waitKey();return0;}

题目三对于下面这幅图像,编程实现染色体计数,并附简要处理流程说明。解决方案:图像存在椒盐噪声,所以先利用中值滤波对图像进行去噪处理。进行二值化。因为图像中染色体内、染色体间存在空白点,所以要进行腐蚀操作。接下来就是要求以上图像存在的染色体的个数了。抛开数字图像处理的专业性知识,利用我们以往掌握的知识,该怎么去做呢?在数据结构中,我们学到过连通区域、深度优先遍历等知识。那么,我们是不是把上图看做是由一个个染色体组成的连通区域呢?没错,求染色体的个数转化为求连通区域〔黑色区域〕的个数。一次DFS〔深度优先遍历〕便可以求得一个连通区域,也就是求得存在一个染色体。我们都知道DFS最简单的实现方式是使用递归函数。递归调用是个很美的函数,但是递归函数调用也会带来开栈、清栈性能上的损失。虽然以上算法性能上不是最优的,但是也不失为一种解决方法。以下是利用数字图像处理里的相关知识:利用OpenCV里的findContours函数检测染色体边缘,然后统计染色体个数。根据我们观察,以上图像含有46个染色体,但是我们求出来的是47条。根据我的个人理解:整个图像的边缘构成了一个最大的轮廓线,所以正确的染色体个数应为46,而不是47。=.=口说无凭,还是拿代码来说话。我们可以把轮廓的坐标打印出来:for(inti=0;i<contours.size();i++){for(intj=0;j<contours[i].size();j++){cout<<contours[i][j]<<"";}cout<<";"<<endl;}打印出:[1,1][1,410][523,410][523,1]。而我们的染色体这幅图片的大小为:525*412。虽然略有偏差,但是足可以证明以上假设。详细代码:#include<opencv2/opencv.hpp>#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>#include<iostream>#include<vector>usingnamespacestd;usingnamespacecv;intmain(intargc,char**argv){Matgray,src,dst;//翻开图像src=imread("image.png");if(src.empty()){cout<<"翻开图像失败!"<<endl;return-1;}cout<<"rows="<<src.rows<<endl;cout<<"cols="<<src.cols<<endl;//转换为灰度图cvtColor(src,gray,CV_BGR2GRAY);//中值滤波medianBlur(gray,gray,7);//图像二值化threshold(gray,dst,170,255,THRESH_BINARY);//腐蚀,默认内核3*3erode(dst,dst,Mat());//erode(dst,dst,Mat());Matcanny_output;vector<vector<Point>>contours;vector<Vec4i>hierarchy;//画轮廓线Canny(dst,canny_output,100,100*2,3);//检测轮廓findContours(dst,contours,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0));cout<<"一共检测到染色体数目:"<<contours.size()-1<<endl;//显示图片imshow("src",src);imshow("canny_output",canny_output);//将图片保存到文件imwrite("dst.png",canny_output);//等待用户输入waitKey();return0;}

题目四对MNIST手写数字数据库〔可在网上搜索下载〕,编程实现来提取其链码。解决方案:将Mnist字库读取到以OpenCV里的Mat为储存单元的vector中。使用findContours将链码保存在vector中。输出链码。#include<opencv2/opencv.hpp>#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>#include<iostream>#include<vector>#include<string>#include<fstream>usingnamespacestd;usingnamespacecv;//格式转换intReverseInt(inti){unsignedcharch1,ch2,ch3,ch4;ch1=i&255;ch2=(i>>8)&255;ch3=(i>>16)&255;ch4=(i>>24)&255;return((int)ch1<<24)+((int)ch2<<16)+((int)ch3<<8)+ch4;}/***将Mnist数据库读取到OpenCV::Mat格式中*格式:*magicnumber*numberofimages*rows*cols*averyverylongvectorcontainsalldigits*/voidread_Mnist(stringfilename,vector<Mat>&vec){ifstreamfile(filename,ios::binary);if(file.is_open()){intmagic_number=0;intnumber_of_images=0;intn_rows=0;intn_cols=0;file.read((char*)&magic_number,sizeof(magic_number));magic_number=ReverseInt(magic_number);file.read((char*)&number_of_images,sizeof(number_of_images));number_of_images=ReverseInt(number_of_images);file.read((char*)&n_rows,sizeof(n_rows));n_rows=ReverseInt(n_rows);file.read((char*)&n_cols,sizeof(n_cols));n_cols=ReverseInt(n_cols);for(inti=0;i<number_of_images;++i){cv::Mattp=Mat::zeros(n_rows,n_cols,CV_8UC1);for(intr=0;r<n_rows;++r){for(intc=0;c<n_cols;++c){unsignedchartemp=0;file.read((char*)&temp,sizeof(temp));tp.at<uchar>(r,c)=(int)temp;}}vec.push_back(tp);}}//if}intmain(intargc,char**argv){intcount=1;//存储Mnist字库vector<Mat>vec;//将Mnist字库读取到vector中read_Mnist("t10k-images.idx3-ubyte",vec);cout<<"共含有:"<<vec.size()<<"幅图片"<<endl;for(autoiter=vec.begin();iter!=vec.end();iter++){cout<<"第"<<count++<<"幅图片..."<<endl;//显示Mnist字库imshow("Mnist",*iter);vector<vector<Point>>contours;//读取轮廓findContours(*iter,contours,CV_RETR_EXTERNAL,CV_CHAIN_CODE);//输出链码for(inti=0;i<contours.size();i++){for(intj=0;j<contours[i].size();j++){cout<<contours[i][j];}cout<<endl;}waitKey(1000);}waitKey();return0;}效果图:从以上输出看到,我们所得到的链码并不是我们所熟悉的4方向和8方向的链码。无论是在StackOverFlow还是知乎、Google均没有找到相关资料。不得不说是一个遗憾。

总结以下是自己完本钱次论文所学

温馨提示

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

评论

0/150

提交评论