一、函数介绍
前面讲了,Emgu CV中常见的线性滤波有均值滤波、方框滤波、高斯滤波,他们的滤波核是由Emgu CV相关函数生成,应该是固定不变的。为了提高灵活性,Emgu CV还支持自定义滤波核进行图像的平滑操作,这个函数就是Filter2D()。
官方定义如下:
public static void Filter2D(
IInputArray src, // 输入图像
IOutputArray dst, // 输出图像
IInputArray kernel, // 滤波核的大小,也就是选取的邻域像素的高度和宽度。
Point anchor, // 锚点,默认值是(-1,-1),表示当前计算均值的点位于核的中心点位置。
double delta = 0.0, // 可选值,滤波后添加到像素的值。
BorderType borderType = BorderType.Reflect101 // 边界样式,一般选默认。
)
Filter2D()使用起来更加灵活,能够根据实际图像的不同颜色特征设计不同的滤波核,但是滤波核如何设计,采用的滤波核大小、权重都需要多次试验才能找到更好的结果。
注意:Filter2D()是线性滤波。
二、举例
1.原始素材
原始素材定义为srcMat,如下:
2.过滤水平方向的直线
利用Filter2D()函数自定义一个滤波核,将srcMat中的白色水平直线去掉,只保留其它方向白色的直线,代码可以这样写:
Mat tempMat = srcMat.Clone();
Mat gray = new Mat();
CvInvoke.CvtColor(tempMat, gray, ColorConversion.Bgr2Gray);
int[,,] data = new[,,]
{
{
{ -1 },
{ 2 },
{ -1 }
},
{
{ -1 },
{ 2 },
{ -1 }
},
{
{ -1 },
{ 2 },
{ -1 }
}
};
Image<Gray, int> kernel = new Image<Gray, int>(data);
CvInvoke.Filter2D(gray, gray, kernel, new System.Drawing.Point(-1, -1));
其实这个滤波核就是3 * 3大小,中间垂直方向都是2,两边垂直方向是-1,这样在平滑(或者叫滤波、卷积都行)时,只有每一行三个数相加都是0,这样就保证水平方向值是0了。具体文字描述我也说不清,读者们自己体会一下。
代码执行结果如下:
3.过滤垂直方向的直线
这个正好和上面的相反,其实只要替换一个滤波核就可以,其它的代码不用变,这次的滤波核是:
执行结果是:
4.保留45度角方向的直线,滤波核是9
前面的都是3 * 3大小的滤波核,这次换一个 9 * 9大小的,并且只保留srcMat中45度角方向的直线,其余角度的直线尽可能的过滤掉,滤波核是这样的:
执行结果是这样的:
原创不易,请勿抄袭。共同进步,相互学习。