一个矩阵与另一个矩阵的卷积运算大部分运用在图像处理上,例如用一个模板去对一幅图像进行卷积。
卷积方法:
1、函数法(fileter2D)
2、对应项相乘求和CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth,InputArray kernel, Point anchor=Point(-1,-1),double delta=0, int borderType=BORDER_DEFAULT );
把模板(n*n)放在矩阵上(中心对准要处理的元素),用模板的每个元素去乘矩阵中的的元素,累加和等于这个元素,例如例子中的第二行第二个元素24= 1*(-3)+2*(-3)+3*5+2*(-3)+3*0+4*5+3*(-3)+4*(-3)+5*5的计算,依次计算每个元素的值,如果矩阵的中心在边缘就要将原矩阵进行扩展,例如补0,或者直接规定模板的中心距离边缘(n-1)/2个单位以上。
代码:
#include <QtCore/QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
/**********对n*m的图像求卷积***************/
Mat src,dst,Mdst;
Mat Km = (Mat_<float>(3,3) << 1.0, -2.0, 1.0, 4.0, -2.0 , -1.0, 4.0, -2.0, 2.0);
src = imread("../convolution/lena.png",1);
dst.create(src.rows,src.cols,src.type());
imshow("src",src);
filter2D(src,dst,src.depth(),Km,Point(-1,-1));
imshow("filtering",dst);
/**********求与卷积和同大小的矩阵的卷积***************/
//(1)使用卷积函数filter2D()
Mat M0 = (Mat_<float>(3,3) << -3,-3,5,-3,0,5,-3,-3,5);
Mat Msrc = (Mat_<float>(3,3) << 1,2,3,2,3,4,3,4,5);
filter2D(Msrc,Mdst,Msrc.depth(),M0,Point(-1,-1));
cout<<"Mdst = "<<Mdst<<endl;
//(2)源矩阵与卷积和对应项相乘求和,所求得的值对应(1)中中心点的值
float mm=0;
for(int i=0;i<Msrc.rows;i++)
for(int j=0;j<Msrc.cols;j++)
mm+=Msrc.ptr<float>(i)[j]*M0.ptr<float>(i)[j];
cout<<endl<<"mm = "<<(float)mm<<endl;
waitKey(0);
return a.exec();
}
运行结果:
(1)用函数filter2D()对图像卷积
(2)对3*3矩阵Msrc = (1,2,3;2,3,4;3,4,5)卷积
由结果可以看出mm=24即为函数filter2D求得的卷积矩阵Mdst中心点的值.
结论:
1.求卷积矩阵的元素x,y时,对准Msrc矩阵的x,y元素。
2.然后 M0矩阵从1,1朝右朝下移动,Msrc从x,y朝左朝上移动。
3.对应元素相乘、相加即可。