a.运用一对卷积阵列 (分别作用于X和 Y 方向,这里采用sobel算子):
b.使用下列公式计算梯度幅值和方向:
代码:
Mat SobleFilter::sobleFilte(Mat* src_mat,Mat* x_mat,Mat* y_mat,int n)
{
Mat src=(Mat)*src_mat;
Mat x_array=(Mat)*x_mat;
Mat y_array=(Mat)*y_mat;
Mat dst;
dst.create( src.rows,src.cols, src.type() );
double xb,xg,xr,yb,yg,yr;
int nextX,nextY;
for(int row=0; row<src.rows; row++)
{
for(int col=0; col<src.cols; col++)
{
for(int subRow=-n; subRow<=n; subRow++)
{
for(int subCol=-n; subCol<=n; subCol++)
{
nextX=col+subCol;
nextY=row+subRow;
if(nextX < 0)
{
nextX = 0;
}
if(nextX > src.cols)
{
nextX = src.cols;
}
if(nextY < 0)
{
nextY = 0;
}
if(nextY > src.rows)
{
nextY = src.rows;
}
xb += x_array.at<double>(subRow+n,subCol+n)* src.at<Vec3b>(nextY,nextX)[0];
xg += x_array.at<double>(subRow+n,subCol+n)* src.at<Vec3b>(nextY,nextX)[1];
xr += x_array.at<double>(subRow+n,subCol+n)* src.at<Vec3b>(nextY,nextX)[2];
yb +=y_array.at<double>(subRow+n,subCol+n)* src.at<Vec3b>(nextY,nextX)[0];
yg +=y_array.at<double>(subRow+n,subCol+n)* src.at<Vec3b>(nextY,nextX)[1];
yr +=y_array.at<double>(subRow+n,subCol+n)* src.at<Vec3b>(nextY,nextX)[2];
}
}
dst.at<Vec3b>(row,col)[0]=detectNum(sqrt(xb*xb+yb+yb));
dst.at<Vec3b>(row,col)[1]=detectNum(sqrt(xg*xg+yg+yg));
dst.at<Vec3b>(row,col)[2]=detectNum(sqrt(xr*xr+yr+yr));
nextY=0;
nextX=0;
xb=xg=xr=0;
yb=yg=yr=0;
}
}
return dst;
}
///越界检测
int SobleFilter::detectNum(int value)
{
return value < 0 ? 0 : (value > 255 ? 255 : value);
}