概述
最近做一些图像处理的工作,搜寻资料发现很多大家都推荐导向滤波,不过这类大都是opencv的代码较多,所以我仿照网上的一些资料转了一份C#版本,如有错误请指正,互相交流学习。
开发环境:vs2017,win10。EmguCV通过“项目→管理NuGet程序包”,搜索emgucv导入即可。
代码如下:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
public static class PictureProcessing
{
public static Bitmap GuidedFilter(Mat srcMat, Mat guidedMat, int radius, double eps)
{
//------------【0】转换源图像信息,将输入扩展为64位浮点型,以便以后做乘法------------
srcMat.ConvertTo(srcMat, DepthType.Cv64F);
guidedMat.ConvertTo(guidedMat, DepthType.Cv64F);
//--------------【1】各种均值计算----------------------------------
Mat mean_p = new Mat();
Mat mean_I = new Mat();
Mat mean_Ip = new Mat();
Mat mean_II = new Mat();
CvInvoke.BoxFilter(srcMat, mean_p, DepthType.Cv64F, new Size(radius, radius), new Point(-1, -1));//生成待滤波图像均值mean_p
CvInvoke.BoxFilter(guidedMat, mean_I, DepthType.Cv64F, new Size(radius, radius), new Point(-1, -1));//生成引导图像均值mean_I
Mat sg = new Mat();
Mat gg = new Mat();
CvInvoke.Multiply(srcMat, guidedMat, sg);
CvInvoke.Multiply(guidedMat, guidedMat, gg);
CvInvoke.BoxFilter(sg, mean_Ip, DepthType.Cv64F, new Size(radius, radius), new Point(-1, -1));//生成互相关均值mean_Ip
CvInvoke.BoxFilter(gg, mean_II, DepthType.Cv64F, new Size(radius, radius), new Point(-1, -1));//生成引导图像自相关均值mean_II
//--------------【2】计算相关系数,计算Ip的协方差cov和I的方差var------------------
Mat cov_Ip = new Mat();
Mat Ip = new Mat();
CvInvoke.Multiply(mean_I, mean_p, Ip);
CvInvoke.Subtract(mean_Ip, Ip, cov_Ip);
Mat var_I = new Mat();
Mat II = new Mat();
CvInvoke.Multiply(mean_I, mean_I, II);
CvInvoke.Subtract(mean_II, II, var_I);
//---------------【3】计算参数系数a、b-------------------
Mat a = new Mat();
Mat b = new Mat();
Mat I_eps = new Mat();
CvInvoke.Add(var_I, new ScalarArray(eps), I_eps);
CvInvoke.Divide(cov_Ip, I_eps, a);
Mat aI = new Mat();
CvInvoke.Multiply(a, mean_I, aI);
CvInvoke.Subtract(mean_p, aI, b);
//--------------【4】计算系数a、b的均值-----------------
Mat mean_a = new Mat();
Mat mean_b = new Mat();
CvInvoke.BoxFilter(a, mean_a, DepthType.Cv64F, new Size(radius, radius), new Point(-1, -1));
CvInvoke.BoxFilter(b, mean_b, DepthType.Cv64F, new Size(radius, radius), new Point(-1, -1));
//---------------【5】生成输出矩阵------------------
Mat axsrc = new Mat();
CvInvoke.Multiply(mean_a, srcMat, axsrc);
Mat dstImage = new Mat();
CvInvoke.Add(axsrc, mean_b, dstImage);
mean_p.Dispose();
mean_I.Dispose();
mean_Ip.Dispose();
mean_II.Dispose();
sg.Dispose();
gg.Dispose();
cov_Ip.Dispose();
Ip.Dispose();
var_I.Dispose();
II.Dispose();
a.Dispose();
b.Dispose();
I_eps.Dispose();
aI.Dispose();
mean_a.Dispose();
mean_b.Dispose();
axsrc.Dispose();
return dstImage.Bitmap;
}
}
使用时直接调用:
Mat src = new Mat(openFileDialog.FileName);
pictureBox1.Image = PictureProcessing.GuidedFilter(src, src, 50, 300);
主要就是参数radius和eps的配置,看自己喜好。网上亦有很多改进效率的方法,还在琢磨中。
参考资料:https://blog.csdn.net/sinat_36264666/article/details/77990790
最后
以上就是醉熏吐司为你收集整理的【使用EmguCV进行图像处理】导向滤波的全部内容,希望文章能够帮你解决【使用EmguCV进行图像处理】导向滤波所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复