用傅里叶变换加速卷积,直接上代码,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. Linux下开启MySQL的远程连接

    今天在用客户端工具远程连接mysql的时候,连接不上,以为是防火墙,关了防火墙后依然打不开,后开在网上查了下原来mysql基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root ...

  2. codeforces 710C

    C. Magic Odd Square time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. spark-streaming-kafka包源码分析

    转载请注明原创地址 http://www.cnblogs.com/dongxiao-yang/p/5443789.html 最近由于使用sparkstreaming的同学需要对接到部门内部的的kafk ...

  4. 回某位朋友问题备受phpcgi.exe煎熬现在cpu跑满(解决方案)

    (本文原创,但是cgi参数参考一个大神写的针对小服务器的,希望大家积极投票哦) 下面是对php-cgi.ext过多引起服务器cup%的解决方法,希望对大家有帮助;大多数情况是发生在第四项上;   解决 ...

  5. FIREDAC TFDCONNECTION连接MYSQL数据库

    FIREDAC TFDCONNECTION连接MYSQL数据库 procedure TfrmDB.ConnectDB;begin FDMoniFlatFileClientLink1.FileName ...

  6. usb转串口如何配置?

    概述 USB转串口输出,在kernel启动阶段加载相应的usb转串口芯片驱动,加载成功后,可通过usb转串口与pc机端交互. 步骤 1.  在kernel配置中选中usb转串口驱动: 2.  传给内核 ...

  7. OpenCV 最小二乘拟合方法求取直线倾角

    工业相机拍摄的图像中,由于摄像质量的限制,图像中的直线经过处理后,会表现出比较严重的锯齿.在这种情况下求取直线的倾角(其实就是直线的斜率),如果是直接选取直线的开始点和结束点来计算,或是用opencv ...

  8. [React + Mobx] Mobx and React intro: syncing the UI with the app state using observable and observer

    Applications are driven by state. Many things, like the user interface, should always be consistent ...

  9. mybatis0206 延迟加载

    延迟加载 1.1使用延迟加载意义 在进行数据查询时,为了提高数据库查询性能,尽量使用单表查询,因为单表查询比多表关联查询速度要快. 如果查询单表就可以满足需求,一开始先查询单表,当需要关联信息时,再关 ...

  10. Html网页生成Pdf

    在http://code.google.com/p/wkhtmltopdf/downloads/list下载安装程序. 1.添加引用 using System.Diagnostics; 添加引用 2. ...