以下是《OpenCV3编程入门》中6.4.9的示例程序的C# + EMGU 3.4.1版:
有任何问题或疑问,欢迎交流探讨。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
namespace ErodeDilate_OpenClose_TopBlackHat
{
public partial class Form1 : Form
{
//定义全局变量
Mat srcImage = new Mat(), dstImage = new Mat();
ElementShape elementShape = ElementShape.Rectangle;
int maxIterationNum = 10;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//载入原图
srcImage = CvInvoke.Imread("USA_Captain.jpg",ImreadModes.Unchanged);
if (srcImage.IsEmpty)
MessageBox.Show("读取srcImage错误~!");
//显示原始图像
imageBox_src.Image = srcImage;
imageBox_ed.Image = srcImage;
imageBox_oc.Image = srcImage;
imageBox_tb.Image = srcImage;
//TrackBar赋初值
trackBar_ed.Value = maxIterationNum;
trackBar_oc.Value = maxIterationNum;
trackBar_tb.Value = maxIterationNum;
//迭代初始值显示
lable_ed.Text = trackBar_ed.Value.ToString();
lable_oc.Text = trackBar_oc.Value.ToString();
lable_tb.Text = trackBar_tb.Value.ToString();
}
//获取按键信息
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D1) //按下键盘按键1.使用椭圆(Ellipse)结构元素
elementShape = ElementShape.Ellipse;
else if (e.KeyCode == Keys.D2) //按下键盘按键2,使用矩形(Rectangle)结构元素
elementShape = ElementShape.Rectangle;
else if (e.KeyCode == Keys.D3) //按下键盘按键3,使用十字形(Cross)结构元素
elementShape = ElementShape.Cross;
else if (e.KeyCode == Keys.Space) //按下键盘按键Space,在矩形、椭圆、十字形结构元素中循环切换
elementShape = (ElementShape)((Convert.ToInt32(elementShape) + 1) % 3);
}
//腐蚀/膨胀
private void trackBar_ed_Scroll(object sender, EventArgs e)
{
int offset = trackBar_ed.Value - maxIterationNum; //定义偏移量
int absOffset = offset > 0 ? offset : -offset; //偏移量绝对值
//自定义核
Mat element = CvInvoke.GetStructuringElement(elementShape, new Size(absOffset * 2 + 1, absOffset * 2 + 1), new Point(absOffset, absOffset));
//进行操作
if (offset < 0)
CvInvoke.Erode(srcImage, dstImage, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));
else
CvInvoke.Dilate(srcImage, dstImage, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));
imageBox_ed.Image = dstImage; //显示图像
lable_ed.Text = trackBar_ed.Value.ToString(); //显示当前迭代值
}
//开运算/闭运算
private void trackBar_oc_Scroll(object sender, EventArgs e)
{
int offset = trackBar_oc.Value - maxIterationNum; //定义偏移量
int absOffset = offset > 0 ? offset : -offset; //偏移量绝对值
//自定义核
Mat element = CvInvoke.GetStructuringElement(elementShape, new Size(absOffset * 2 + 1, absOffset * 2 + 1), new Point(absOffset, absOffset));
//进行操作
if (offset < 0)
CvInvoke.MorphologyEx(srcImage, dstImage, MorphOp.Open, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));
else
CvInvoke.MorphologyEx(srcImage, dstImage, MorphOp.Close, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));
imageBox_oc.Image = dstImage; //显示图像
lable_oc.Text = trackBar_oc.Value.ToString(); //显示当前迭代值
}
//顶帽运算/黑帽运算
private void trackBar_tb_Scroll(object sender, EventArgs e)
{
int offset = trackBar_tb.Value - maxIterationNum; //定义偏移量
int absOffset = offset > 0 ? offset : -offset; //偏移量绝对值
//自定义核
Mat element = CvInvoke.GetStructuringElement(elementShape, new Size(absOffset * 2 + 1, absOffset * 2 + 1), new Point(absOffset, absOffset));
//进行操作
if (offset < 0)
CvInvoke.MorphologyEx(srcImage, dstImage, MorphOp.Tophat, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));
else
CvInvoke.MorphologyEx(srcImage, dstImage, MorphOp.Blackhat, element, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));
imageBox_tb.Image = dstImage; //显示图像
lable_tb.Text = trackBar_tb.Value.ToString(); //显示当前迭代值
}
}
}
运行效果图: