核心函数:cvFilter2D

原理:

核的中心对准源图像的像素,源图像和核的相对应元素分别相乘并全部相加,得到的值为目标图像核心的值;对于边界则默认用最边界的元素值填充出一个虚拟外边界(相当于调用cvCopyMakeBorder,cvFilter2D内置这个函数)

程序:

wKioL1PsMmmT73t5AAG0k3n2fJs452.jpg

代码:

#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
int convolution(int argc,char** argv)
{
IplImage* src=cvCreateImage(cvSize(10,10),8,1); //源图像,注意只有CV_8UC1的类型可以修改其中的值,如果为float则不能用cvSet,cvZero或者直接用for语句修改其中的值
//for(int rows=0;rows<src->height;rows++)
//{
//uchar *data=(uchar*)(src->imageData+rows*src->widthStep);
//for(int cols=0;cols<src->width;cols++)
//{
//uchar *result=(uchar *)(data+cols*src->nChannels);
//*result=1;
//}
//}
//cvZero(src);
cvSet(src,cvScalar(1));
IplImage* dst=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
cvZero(dst);
CvMat kernel;
float kerneldata[]={1,1,1,          //核必须为float
              1,1,1,
  1,1,1
};
cvInitMatHeader(&kernel,3,3,CV_32FC1,(void*)kerneldata); //核心必须为浮点型
cvFilter2D(src,dst,&kernel);
std::cout<<"srcMat:"<<std::endl;
for(int rows=0;rows<src->height;rows++)
{
uchar *data=(uchar*)(src->imageData+rows*src->widthStep);
for(int cols=0;cols<src->width;cols++)
{
uchar result=*(data+cols*src->nChannels);
std::cout<<(int)result<<" ";
}
std::cout<<std::endl;
}
std::cout<<"kernelMat:"<<std::endl;
for(int rows=0;rows<kernel.height;rows++)
{
float *data=(float*)(kernel.data.ptr+rows*kernel.step);
for(int cols=0;cols<kernel.width;cols++)
{
float result=*(data+cols);
std::cout<<result<<" ";
}
std::cout<<std::endl;
}
std::cout<<"ConvolutionDstMat:"<<std::endl;
for(int rows=0;rows<dst->height;rows++)
{
uchar *data=(uchar*)(dst->imageData+rows*dst->widthStep);
for(int cols=0;cols<dst->width;cols++)
{
uchar result=*(data+cols*dst->nChannels);
std::cout<<(int)result<<" ";
}
std::cout<<std::endl;
}
return 0;
}