用傅里叶变换加速卷积,直接上代码,Mat版是Copy他人的。

CvMat版

 #include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <iostream> using namespace cv;
using namespace std; void speedy_convolution(const CvMat* A,const CvMat* B,CvMat* C); int main()
{
IplImage* img=cvLoadImage("C:/Users/shark/Desktop/fruits.jpg",);
CvMat* src=cvCreateMat(img->height,img->width,CV_32FC1);
/*int data;
for(int i=0;i<img->height;i++)
{
for(int j=0;j<img->width;j++)
{
data=img->imageData[i*img->widthStep+j];
cvmSet(src,i,j,data);
}
}*/
//必须归一化矩阵的值为0-1之间(缩放比例在1/255.0附近效果最好,太小最后会全黑,接近1或大于1几乎是全白;
//(还未深入了解函数cvConvertScale的机理),缩放比例不能为1,打出目标图像的像素有正有负
cvConvertScale(img,src,/255.0,); CvMat* kernel=cvCreateMat(,,CV_32FC1);
cvSetReal2D(kernel,,,1.0/); cvSetReal2D(kernel,,,2.0/); cvSetReal2D(kernel,,,1.0/); //注意设置值时必须加个.0否则1/16的值0
cvSetReal2D(kernel,,,2.0/); cvSetReal2D(kernel,,,4.0/); cvSetReal2D(kernel,,,2.0/);
cvSetReal2D(kernel,,,1.0/); cvSetReal2D(kernel,,,2.0/); cvSetReal2D(kernel,,,1.0/);
CvMat* C=cvCreateMat((src->rows+kernel->rows-),(src->cols+kernel->cols-),src->type);
speedy_convolution(src,kernel,C); IplImage* img_src=cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,);
cvGetImage(src,img_src);
IplImage* img_dst=cvCreateImage(cvGetSize(C),IPL_DEPTH_32F,);
cvGetImage(C,img_dst); cvNamedWindow("img_src");
cvShowImage("img_src",img_src);
cvNamedWindow("img");
cvShowImage("img",img);
cvNamedWindow("dst");
cvShowImage("dst",img_dst);
cvWaitKey();
return ;
} void speedy_convolution(
const CvMat* A,
const CvMat* B,
CvMat* C
){
int dft_M=cvGetOptimalDFTSize(A->rows+B->rows-);
int dft_N=cvGetOptimalDFTSize(A->cols+B->cols-); CvMat *dft_A=cvCreateMat(dft_M,dft_N,A->type);
CvMat *dft_B=cvCreateMat(dft_M,dft_N,B->type);
CvMat tmp;
cvGetSubRect(dft_A,&tmp,cvRect(,,A->cols,A->rows));
cvCopy(A,&tmp);
cvGetSubRect(dft_A,&tmp,cvRect(A->cols,,dft_A->cols-A->cols,A->rows));
cvZero(&tmp);
cvDFT(dft_A,dft_A,CV_DXT_FORWARD,A->rows); cvGetSubRect(dft_B,&tmp,cvRect(,,B->cols,B->rows));
cvCopy(B,&tmp);
cvGetSubRect(dft_B,&tmp,cvRect(B->cols,,dft_B->cols-B->cols,B->rows));
cvZero(&tmp);
cvDFT(dft_B,dft_B,CV_DXT_FORWARD,B->rows); cvMulSpectrums(dft_A,dft_B,dft_A,); cvDFT(dft_A,dft_A,CV_DXT_INV_SCALE,C->rows);
cvGetSubRect(dft_A,&tmp,cvRect(,,C->cols,C->rows));
cvCopy(&tmp,C);
cvReleaseMat(&dft_A);
cvReleaseMat(&dft_B);
}

Mat版

 #include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream> using namespace cv;
using namespace std; //http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft[2]
void convolveDFT(Mat A, Mat B, Mat& C)
{
// reallocate the output array if needed
C.create(abs(A.rows - B.rows)+, abs(A.cols - B.cols)+, A.type());
Size dftSize;
// calculate the size of DFT transform
dftSize.width = getOptimalDFTSize(A.cols + B.cols - );
dftSize.height = getOptimalDFTSize(A.rows + B.rows - ); // allocate temporary buffers and initialize them with 0's
Mat tempA(dftSize, A.type(), Scalar::all());
Mat tempB(dftSize, B.type(), Scalar::all()); // copy A and B to the top-left corners of tempA and tempB, respectively
Mat roiA(tempA, Rect(,,A.cols,A.rows));
A.copyTo(roiA);
Mat roiB(tempB, Rect(,,B.cols,B.rows));
B.copyTo(roiB); // now transform the padded A & B in-place;
// use "nonzeroRows" hint for faster processing
dft(tempA, tempA, , A.rows);
dft(tempB, tempB, , B.rows); // multiply the spectrums;
// the function handles packed spectrum representations well
mulSpectrums(tempA, tempB, tempA, DFT_COMPLEX_OUTPUT);
//mulSpectrums(tempA, tempB, tempA, DFT_REAL_OUTPUT); // transform the product back from the frequency domain.
// Even though all the result rows will be non-zero,
// you need only the first C.rows of them, and thus you
// pass nonzeroRows == C.rows
dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows); // now copy the result back to C.
tempA(Rect(, , C.cols, C.rows)).copyTo(C); // all the temporary buffers will be deallocated automatically
} int main(int argc, char* argv[])
{
const char* filename = argc >= ? argv[] : "Lenna.png"; Mat I = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
if( I.empty())
return -; Mat kernel = (Mat_<float>(,) << , , , , , , , , );
cout << kernel; Mat floatI = Mat_<float>(I);// change image type into float
Mat filteredI;
convolveDFT(floatI, kernel, filteredI); normalize(filteredI, filteredI, , , CV_MINMAX); // Transform the matrix with float values into a
// viewable image form (float between values 0 and 1).
imshow("image", I);
imshow("filtered", filteredI);
waitKey(); } //一是输出Mat C应声明为引用;二是其中的mulSpectrums函数的第四个参数flag值没有指定,应指定为DFT_COMPLEX_OUTPUT或是DFT_REAL_OUTPUT. //main函数中首先按灰度图读入图像,然后创造一个平滑核kernel,将输入图像转换成float类型(注意这步是必须的,因为dft只能处理浮点数),在调用convolveDFT求出卷积结果后,将卷积结果归一化方便显示观看。 //需要注意的是,一般求法中,利用核游走整个图像进行卷积运算,实际上进行的是相关运算,真正意义上的卷积,应该首先把核翻转180度,再在整个图像上进行游走。OpenCV中的filter2D实际上做的也只是相关,而非卷积。

学习opencv 第六章 习题十三的更多相关文章

  1. JVM学习笔记-第六章-类文件结构

    JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...

  2. C Primer Plus 学习笔记 -- 前六章

    记录自己学习C Primer Plus的学习笔记 第一章 C语言高效在于C语言通常是汇编语言才具有的微调控能力设计的一系列内部指令 C不是面向对象编程 编译器把源代码转化成中间代码,链接器把中间代码和 ...

  3. 【学习opencv第六篇】图像的反转操作

    考试终于完了,现在终于有时间可以继续学习这个了.写这篇博客主要是因为以前一直搞不清楚图像数据到底是怎么存储的,以及这个step到底是什么,后来查了一下才知道原来step就是数据行的长度.. #incl ...

  4. 《mysql必知必会》学习_第六章_20180730_欢

    第六章<过滤数据> P35 1. select prod_name,prod_price from products where prod_price=2.5; 2.select prod ...

  5. Linux学习笔记(第六章)

    第六章-档案权限与目录配置#chgrp:改变档案的所属群组#chown:改变档案的拥有者#chmod:改变档案的权限及属性 chown用法 chmod用法: r:4 w:2 x:1对于文档: 对于目录 ...

  6. C++ Primer Plus学习:第六章

    C++入门第六章:分支语句和逻辑运算符 if语句 语法: if (test-condition) statement if else语句 if (test-condition) statement1 ...

  7. o'Reill的SVG精髓(第二版)学习笔记——第六章

    第六章:坐标系统变换 想要旋转.缩放或者移动图片到新的位置.可以给对应的SVG元素添加transform属性. 6.1 translate变换 可以为<use>元素使用x和y属性,以在特性 ...

  8. 学习笔记 第六章 使用CSS美化图片

    第六章  使用CSS美化图片 6.1  在网页中插入图片 GIF图像 跨平台能力,无兼容性问题: 具有减少颜色显示数目而极度压缩文件的能力,不会降低图像的品质(无损压缩): 支持背景透明功能,便于图像 ...

  9. Perl语言入门:第六章习题:处理用户所指定的名字并汇报相应的姓。

    37 print "\n----------------------------------_exercise_6_1--------------------------\n";  ...

随机推荐

  1. MenuDrawer的使用

    ---恢复内容开始--- MenuDrawer框架是一个可以实现上下左右滑动的框架,在使用中可以在xml文件中配置也可以在java代码中实现效果的配置 可以以jar的形式或依赖的形式存在      用 ...

  2. 终端command总结

    Ctrl+Alt+Delete Ctrl+Shift+Esc Ctrl+D Alt+F4 Shift+F10 win+m Ctrl+Alt+. Ctrl+A Ctrl+S osk taskmgr cm ...

  3. BA/PM Competency Module

    No Competency Description BA Weight% PM Weight% 1 Business Analysis:BA   Track Maps   process flows, ...

  4. C# 自动登录网页,浏览页面【转载】

    需求:客户的数据同时存在在另外一个不可控的系统中,需要和当前系统同步. 思路:自动登录另外一个系统,然后抓取数据,同步到本系统中. 技术点:模拟用户登录:保存登录状态:抓取数据 /// <sum ...

  5. Delphi TFindDialog TReplaceDialog对话框在Memo中的使用

    Delphi TFindDialog TReplaceDialog对话框的使用 下载地址1: http://download.csdn.net/detail/teststudio/6408383   ...

  6. 清理yum源

    最近想在美国VPS上装个Wine 可是在执行yum install wine时却遇到了意想不到的错误 系统提示: You could try using –skip-broken to work ar ...

  7. Qt 学习之路 :使用 QJson 处理 JSON

    XML 曾经是各种应用的配置和传输的首选方式.但是现在 XML 遇到了一个强劲的对手:JSON.我们可以在 这里 看到有关 JSON 的语法.总体来说,JSON 的数据比 XML 更紧凑,在传输效率上 ...

  8. xml写代码

    #include <QDomDocument> #include <QtGui> int main(int argc, char *argv[]) { QApplication ...

  9. SpringMVC + Spring 3.2.14 + Hibernate 3.6.10 集成详解

    注:此文档只说明简单的框架集成,各个框架的高级特性未涉及,刚刚接触框架的新人可能需要参考其他资料. PS:本次练习所用jar包都能在此下载到:http://pan.baidu.com/s/1sjmgd ...

  10. linux ptrace I

    这几天通过<游戏安全--手游安全技术入门这本书>了解到linux系统中ptrace()这个函数可以实现外挂功能,于是在ubuntu 16.04 x86_64系统上对这个函数进行了学习. 参 ...