在opencv 中Mat可以进行矩阵运算,Sobel可以求矩阵的梯度,函数接口和参数含义如下:
CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,int dx, int dy, int ksize=3,double scale=1, double delta=0,int borderType=BORDER_DEFAULT );
src:要求梯度的矩阵
dst:梯度求出后存放结果的数组
ddepth:深度,一般与src深度相同,用src.depth()表示
dx:dx=1表示求x方向的一阶梯度,dx=0,不求x方向
dy:dy=1表示求y方向的一阶梯度,dy=0,不求y方向
ksize:核函数的大小
scale:梯度值的尺度大小
delta:delta=0时,表示梯度为0的地方值为0,delta=m表示梯度为0的地方值为m,梯度不为0处值加m
borderType:矩阵的四条边界处,求梯度的类型
Mat mat(10,16,CV_64F);
mat.setTo(2);
//在mat中生成一个局部为-2的矩形
for (int i=0;i<mat.rows;i++)
{
//第3到6行
if (i>2&&i<7)
{
for (int j=0;j<mat.cols;j++)
{
//第4到8列
if (j>3&&j<9)
{
mat.row(i).col(j).setTo(-2);
}
}
}
}
int nnn=mat.channels();
cout<<mat<<endl;
运行结果:
//分别求x y方向的一阶梯度
Mat sobleX,sobleY;
Sobel(mat,sobleX,mat.depth(),1,0,1,1,0,BORDER_DEFAULT); //X方向
Sobel(mat,sobleY,mat.depth(),0,1,1,1,0,BORDER_DEFAULT); //X方向
cout<<sobleX<<endl;
cout<<sobleY<<endl;
运行结果:
//求xy的一阶梯度
Sobel(mat,sobleX,mat.depth(),1,1,1,1,0,BORDER_DEFAULT); //XY方向同时求梯度
cout<<sobleX<<endl;
运行结果:
//修改核函数kSize为3
Sobel(mat,sobleX,mat.depth(),1,0,3,1,0,BORDER_DEFAULT);
cout<<sobleX<<endl;
运行结果:
//修改scale尺度 梯度处值发生变化
Sobel(mat,sobleX,mat.depth(),1,0,1,0.5,0,BORDER_DEFAULT);
cout<<sobleX<<endl;
运行结果:
//修改delta值 非梯度和梯度处值均发生变化
Sobel(mat,sobleX,mat.depth(),1,0,1,0.5,2,BORDER_DEFAULT);
cout<<sobleX<<endl;
运行结果:
//修改边界的类型,边界处值发生变化
Sobel(mat,sobleX,mat.depth(),1,0,1,0.5,0,BORDER_CONSTANT);
cout<<sobleX<<endl;
运行结果:
在matlab中进行梯度计算的函数是gradient,若要使opencv中的Sobel函数与matlab中的gradient函数运算结果一致,则对应的参数设置如下所示:
Sobel(mat,sobleX,mat.depth(),1,0,1,0.5,0); //X方向
Sobel(mat,sobleY,mat.depth(),1,0,1,0.5,0); //X方向
mat=ones(10,16)
mat=mat*2
mat(4:7,5:9)=-2
[ux,uy]=gradient(mat) %ux表示x方向,与sobleX对应。uy表示y方向,与sobleY对应
运算结果: