zoukankan      html  css  js  c++  java
  • 学习opencv 第六章 习题十三

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

    CvMat版

     1 #include "stdafx.h"
     2 #include "cv.h"
     3 #include "highgui.h"
     4 #include <iostream>
     5 
     6 using namespace cv;
     7 using namespace std;
     8 
     9 void speedy_convolution(const CvMat* A,const CvMat* B,CvMat* C);
    10 
    11 int main()
    12 {
    13     IplImage* img=cvLoadImage("C:/Users/shark/Desktop/fruits.jpg",0);
    14     CvMat* src=cvCreateMat(img->height,img->width,CV_32FC1);
    15     /*int data;
    16     for(int i=0;i<img->height;i++)
    17     {
    18         for(int j=0;j<img->width;j++)
    19         {
    20             data=img->imageData[i*img->widthStep+j];
    21             cvmSet(src,i,j,data);
    22         }
    23     }*/
    24     //必须归一化矩阵的值为0-1之间(缩放比例在1/255.0附近效果最好,太小最后会全黑,接近1或大于1几乎是全白;
    25     //(还未深入了解函数cvConvertScale的机理),缩放比例不能为1,打出目标图像的像素有正有负
    26     cvConvertScale(img,src,1/255.0,0);  
    27     
    28 
    29     CvMat* kernel=cvCreateMat(3,3,CV_32FC1);
    30     cvSetReal2D(kernel,0,0,1.0/16);    cvSetReal2D(kernel,0,1,2.0/16); cvSetReal2D(kernel,0,2,1.0/16);    //注意设置值时必须加个.0否则1/16的值0
    31     cvSetReal2D(kernel,1,0,2.0/16);    cvSetReal2D(kernel,1,1,4.0/16); cvSetReal2D(kernel,1,2,2.0/16);
    32     cvSetReal2D(kernel,2,0,1.0/16);    cvSetReal2D(kernel,2,1,2.0/16); cvSetReal2D(kernel,2,2,1.0/16);
    33     CvMat* C=cvCreateMat((src->rows+kernel->rows-1),(src->cols+kernel->cols-1),src->type);
    34     speedy_convolution(src,kernel,C);
    35 
    36     IplImage* img_src=cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);
    37     cvGetImage(src,img_src);
    38     IplImage* img_dst=cvCreateImage(cvGetSize(C),IPL_DEPTH_32F,1);
    39     cvGetImage(C,img_dst);
    40 
    41     cvNamedWindow("img_src");
    42     cvShowImage("img_src",img_src);
    43     cvNamedWindow("img");
    44     cvShowImage("img",img);
    45     cvNamedWindow("dst");
    46     cvShowImage("dst",img_dst);
    47     cvWaitKey();
    48     return 0;
    49 }
    50 
    51 void speedy_convolution(
    52     const CvMat* A,
    53     const CvMat* B,
    54     CvMat* C
    55     ){
    56         int dft_M=cvGetOptimalDFTSize(A->rows+B->rows-1);
    57         int dft_N=cvGetOptimalDFTSize(A->cols+B->cols-1);
    58 
    59         CvMat *dft_A=cvCreateMat(dft_M,dft_N,A->type);
    60         CvMat *dft_B=cvCreateMat(dft_M,dft_N,B->type);
    61         CvMat tmp;
    62         cvGetSubRect(dft_A,&tmp,cvRect(0,0,A->cols,A->rows));
    63         cvCopy(A,&tmp);
    64         cvGetSubRect(dft_A,&tmp,cvRect(A->cols,0,dft_A->cols-A->cols,A->rows));
    65         cvZero(&tmp);
    66         cvDFT(dft_A,dft_A,CV_DXT_FORWARD,A->rows);
    67 
    68         cvGetSubRect(dft_B,&tmp,cvRect(0,0,B->cols,B->rows));
    69         cvCopy(B,&tmp);
    70         cvGetSubRect(dft_B,&tmp,cvRect(B->cols,0,dft_B->cols-B->cols,B->rows));
    71         cvZero(&tmp);
    72         cvDFT(dft_B,dft_B,CV_DXT_FORWARD,B->rows);
    73 
    74         cvMulSpectrums(dft_A,dft_B,dft_A,0);
    75 
    76         cvDFT(dft_A,dft_A,CV_DXT_INV_SCALE,C->rows);
    77         cvGetSubRect(dft_A,&tmp,cvRect(0,0,C->cols,C->rows));
    78         cvCopy(&tmp,C);
    79         cvReleaseMat(&dft_A);
    80         cvReleaseMat(&dft_B);
    81 }

    Mat版

     1 #include "opencv2/core/core.hpp"
     2 #include "opencv2/imgproc/imgproc.hpp"
     3 #include "opencv2/highgui/highgui.hpp"
     4 #include <iostream>
     5 
     6 using namespace cv;
     7 using namespace std;
     8 
     9 //http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft[2]
    10 void convolveDFT(Mat A, Mat B, Mat& C)
    11 {
    12     // reallocate the output array if needed
    13     C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type());
    14     Size dftSize;
    15     // calculate the size of DFT transform
    16     dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1);
    17     dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1);
    18 
    19     // allocate temporary buffers and initialize them with 0's
    20     Mat tempA(dftSize, A.type(), Scalar::all(0));
    21     Mat tempB(dftSize, B.type(), Scalar::all(0));
    22 
    23     // copy A and B to the top-left corners of tempA and tempB, respectively
    24     Mat roiA(tempA, Rect(0,0,A.cols,A.rows));
    25     A.copyTo(roiA);
    26     Mat roiB(tempB, Rect(0,0,B.cols,B.rows));
    27     B.copyTo(roiB);
    28 
    29     // now transform the padded A & B in-place;
    30     // use "nonzeroRows" hint for faster processing
    31     dft(tempA, tempA, 0, A.rows);
    32     dft(tempB, tempB, 0, B.rows);
    33 
    34     // multiply the spectrums;
    35     // the function handles packed spectrum representations well
    36     mulSpectrums(tempA, tempB, tempA, DFT_COMPLEX_OUTPUT);
    37     //mulSpectrums(tempA, tempB, tempA, DFT_REAL_OUTPUT);
    38 
    39     // transform the product back from the frequency domain.
    40     // Even though all the result rows will be non-zero,
    41     // you need only the first C.rows of them, and thus you
    42     // pass nonzeroRows == C.rows
    43     dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows);
    44 
    45     // now copy the result back to C.
    46     tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C);
    47 
    48     // all the temporary buffers will be deallocated automatically
    49 }
    50 
    51 
    52 int main(int argc, char* argv[])
    53 {
    54     const char* filename = argc >=2 ? argv[1] : "Lenna.png";
    55 
    56     Mat I = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
    57     if( I.empty())
    58         return -1;
    59 
    60     Mat kernel = (Mat_<float>(3,3) << 1, 1, 1, 1, 1, 1, 1, 1, 1);
    61     cout << kernel;
    62 
    63     Mat floatI = Mat_<float>(I);// change image type into float
    64     Mat filteredI;
    65     convolveDFT(floatI, kernel, filteredI);
    66     
    67     normalize(filteredI, filteredI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
    68                                             // viewable image form (float between values 0 and 1).
    69     imshow("image", I);
    70     imshow("filtered", filteredI);
    71     waitKey(0);
    72 
    73 }
    74 
    75 //一是输出Mat C应声明为引用;二是其中的mulSpectrums函数的第四个参数flag值没有指定,应指定为DFT_COMPLEX_OUTPUT或是DFT_REAL_OUTPUT.
    76 
    77 //main函数中首先按灰度图读入图像,然后创造一个平滑核kernel,将输入图像转换成float类型(注意这步是必须的,因为dft只能处理浮点数),在调用convolveDFT求出卷积结果后,将卷积结果归一化方便显示观看。
    78 
    79 //需要注意的是,一般求法中,利用核游走整个图像进行卷积运算,实际上进行的是相关运算,真正意义上的卷积,应该首先把核翻转180度,再在整个图像上进行游走。OpenCV中的filter2D实际上做的也只是相关,而非卷积。
  • 相关阅读:
    Chrome调试中的奇技淫巧
    正则表达式学习记录
    探寻<a>中的href和onclick
    鼠标事件记录
    读取本地文件并进行处理
    浏览器兼容性问题汇总
    前端经验总结
    PL/sql使用总结
    正反斜杠的使用场景记录
    isEmpty和isBlank的区别
  • 原文地址:https://www.cnblogs.com/luckyboylch/p/4926590.html
Copyright © 2011-2022 走看看