用opencv求图像的快速傅里叶变换和反变换
2016-07-27 11:18
423 查看
首先,在写这篇博文之前,先感谢一下http://www.cnblogs.com/TonyHome/p/4010116.html这篇文章的作者!
接下来贴一下自己结合qt写的测试代码;
其实通过读官方文档,你会发现其实很简单!
接下来贴一下自己结合qt写的测试代码;
DFTWidget::DFTWidget(QWidget *parent) : QWidget(parent), ui(new Ui::DFTWidget) { ui->setupUi(this); connect(ui->open,SIGNAL(clicked(bool)),this,SLOT(openimageSLOT())); connect(ui->DFT,SIGNAL(clicked(bool)),this,SLOT(convertDFTSlot())); connect(ui->DFTshift,SIGNAL(clicked(bool)),this,SLOT(convertDFTshiftSlot())); connect(ui->DFT_INV,SIGNAL(clicked(bool)),this,SLOT(convertDFTinvSlot())); } DFTWidget::~DFTWidget() { delete ui; } void DFTWidget::openimageSLOT() { QString imageName = QFileDialog::getOpenFileName(this,tr("打开图片"),".",tr("Image Files(*.png *.jpg *.bmp *.jpeg)")); //src = cv::imread(imageName.toLatin1().data(),CV_LOAD_IMAGE_GRAYSCALE); std::string filename = imageName.toStdString(); src = cv::imread(filename,CV_LOAD_IMAGE_GRAYSCALE); if(src.empty()) { QMessageBox::information(this,"注意","图像加载失败",QMessageBox::Ok); } QImage image(imageName); ui->label->setPixmap(QPixmap::fromImage(image.scaled(320,240))); } void DFTWidget::convertDFTSlot() { ui->label->clear(); cv::Mat padded; int opw = cv::getOptimalDFTSize(src.cols);//找寻合适尺寸,最好是2,3,5的倍数 int oph = cv::getOptimalDFTSize(src.rows); QString num1; QString num2; ui->opW->setText(num1.setNum(opw)); ui->opH->setText(num2.setNum(oph)); //copymakeborder是用来填充多余的尺寸 cv::copyMakeBorder(src,padded,0,oph-src.rows,0,opw-src.cols,cv::BORDER_CONSTANT,cv::Scalar::all(0)); cv::Mat planes[] = {cv::Mat_<float>(padded),cv::Mat::zeros(padded.size(),CV_32F)}; //cv::Mat complexI; cv::merge(planes,2,complexI); cv::dft(complexI,complexI); cv::split(complexI,planes); // cv::imshow("plane_real",planes[0]); // cv::imshow("plane_inscriber",planes[1]); cv::magnitude(planes[0],planes[1],planes[0]);//计算梯度幅值 cv::Mat log_img = planes[0]; log_img +=cv::Scalar::all(1); cv::log(log_img,log_img);//一般幅值过大,而正常图像的显示在0~255之间,所以用log函数缩小幅值 log_img = log_img(cv::Rect(0,0,log_img.cols & -2,log_img.rows & -2)); dst = log_img.clone(); //cv::normalize(dst,dst,0,1,CV_MINMAX); //运用log之后也不能保证数值一定在显示范围内,所以用normalize函数进一步缩小范围 cv::normalize(dst,dst,0,1,CV_MINMAX); //dst.convertTo(dst,CV_8UC1,255,0);//第一个参数是输出图像,第二个参数是转换类型,第三个参数是尺度因子,第四个参数是偏移量 //cv::imshow("dst",dst); dst = dst * 255; cv::imwrite("dst.jpg",dst); //cv::imshow("dst",dst); //qDebug() << dst.rows <<dst.cols; //dst = 255.0 * dst; // for(int i = 0;i<512;i++) // { // uchar* pdata = dst.ptr<uchar>(i); // for(int j = 0;j<512;j++) // { // pdata[j] = pdata[j] * 255.; // } // } // imshow("dft",dst); // QImage image = QImage(dst.cols,dst.rows,QImage::Format_ARGB32); // for(int i=0;i<image.width();i++) // { // for(int j=0;j<image.height();j++) // { // int pixel = dst.at<uchar>(j,i); // image.setPixel(i,j,qRgb(pixel,pixel,pixel)); // } // } QImage image("dst.jpg"); ui->label->setPixmap(QPixmap::fromImage(image.scaled(320,240))); } void DFTWidget::convertDFTshiftSlot() { cv::Mat dst_2; dst.copyTo(dst_2); int cx = dst.cols/2; int cy = dst.rows/2; cv::Mat q0 = cv::Mat(dst_2,cv::Rect(0,0,cx,cy)); cv::Mat q1 = cv::Mat(dst_2,cv::Rect(cx,0,cx,cy)); cv::Mat q2 = cv::Mat(dst_2,cv::Rect(0,cy,cx,cy)); cv::Mat q3 = cv::Mat(dst_2,cv::Rect(cx,cy,cx,cy)); cv::Mat temp; q0.copyTo(temp); q3.copyTo(q0); temp.copyTo(q3); q1.copyTo(temp); q2.copyTo(q1); temp.copyTo(q2); // cv::imshow("dst_2",dst_2); cv::imwrite("dst_2.jpg",dst_2); // QImage image(dst_2.cols,dst_2.rows,QImage::Format_Indexed8); // image.setColorCount(256); // for(int i=0;i < 256;i++) // { // image.setColor(i,qRgb(i,i,i)); // } // uchar *pSrc = dst_2.data; // for(int row = 0; row < dst_2.rows; row ++) // { // uchar *pDest = image.scanLine(row); // memcpy(pDest, pSrc, dst_2.cols); // pSrc += dst_2.step; // } QImage image("dst_2.jpg"); ui->label->clear(); ui->label->setPixmap(QPixmap::fromImage(image.scaled(320,240))); } void DFTWidget::convertDFTinvSlot() { cv::Mat gaussianBlur(src.size(),CV_32FC2); cv::Mat BTWSD(src.size(),CV_32FC2); float D0 = 3.0e+4 ; QString num1 = ui->opH->text(); QString num2 = ui->opW->text(); int oph = num1.toInt(); int opw = num2.toInt(); cv::Mat origin[2]; cv::split(complexI,origin); QVector<float> v; for(int i=0;i<oph;i++) { float *p = gaussianBlur.ptr<float>(i); float *q = BTWSD.ptr<float>(i); for(int j=0;j<opw;j++) { float d = pow(i - oph/2,2) + pow(j-opw/2,2); //float D = sqrt(pow(i,2)+pow(j,2)); float x = origin[0].at<float>(i,j); float y = origin[1].at<float>(i,j); float D =sqrt(x*x+y*y); v.push_back(D); p[2*j] = expf(-d/D0); p[2*j+1] = expf(-d/D0); q[2*j] = 1 / (1 + pow(D/D0,2)); q[2*j+1] = 1 / (1 + pow(D/D0,2)); } } float max = v[0]; for(int i=1;i<v.size();i++) { if(v[i] > max) max = v[i]; } qDebug() << max ; //cv::multiply(complexI,gaussianBlur,gaussianBlur); cv::multiply(complexI,BTWSD,BTWSD); //cv::dft(gaussianBlur,gaussianBlur,CV_DXT_INVERSE); cv::dft(BTWSD,BTWSD,CV_DXT_INVERSE);//逆变换 //cv::dft(complexI,complexI,CV_DXT_INVERSE); // cv::Mat dstBlur[2]; cv::Mat btwsd[2]; // cv::split(gaussianBlur,dstBlur); cv::split(BTWSD,btwsd); // cv::normalize(dstBlur[0],dstBlur[0],0,1,CV_MINMAX); //cv::normalize(origin[0],origin[0],0,1,CV_MINMAX); cv::normalize(btwsd[0],btwsd[0],0,1,CV_MINMAX); btwsd[0].convertTo(btwsd[0],CV_8UC1,255,0); cv::imwrite("btws.jpg",btwsd[0]); //QImage image = QImage((const uchar*)btwsd[0].data,btwsd[0].cols,btwsd[0].rows,btwsd[0].step,QImage::Format_Indexed8); QImage image("btws.jpg"); ui->label->clear(); ui->label->setPixmap(QPixmap::fromImage(image.scaled(320,240))); //cv::imshow("origin",origin[0]); // cv::imshow("dstblur",dstBlur[0]); // cv::imshow("btwsd",btwsd[0]); }
其实通过读官方文档,你会发现其实很简单!
相关文章推荐
- QT学习 第一章:基本对话框
- 使用Shiboken为C++和Qt库创建Python绑定
- Qt 5.6更新至RC版,最终版本近在咫尺
- Qt定时器和随机数详解
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- Qt实现图片移动实例(图文教程)
- Qt for Android开发实例教程
- Android Studio中配置OpenCV库开发环境的教程
- 基于C++实现kinect+opencv 获取深度及彩色数据
- visual studio 2012安装配置方法图文教程 附opencv配置教程
- OpenCV 2.4.3 C++ 平滑处理分析
- Python中使用OpenCV库来进行简单的气象学遥感影像计算
- 利用Python和OpenCV库将URL转换为OpenCV格式的方法
- python结合opencv实现人脸检测与跟踪
- Python环境搭建之OpenCV的步骤方法
- Python+Opencv识别两张相似图片
- Python实现OpenCV的安装与使用示例
- 在树莓派2或树莓派B+上安装Python和OpenCV的教程