本示例是《OpenCV3编程入门》中7.1.6的综合示例的C# + EMGU 3.4.1版,在这个示例程序中,分别演示了canny边缘检测、sobel边缘检测、Laplacian算子,scharr滤波器的使用,经过详细注释的代码如下:
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.CvEnum;
namespace SyntheticExample_EdgeDetection
{
public partial class Form1 : Form
{
//原始图像
Mat g_srcImage = new Mat();
//Canny边缘检测相关变量
Mat g_cannyDetectedEdges = new Mat();
int g_cannyLowThreshold = 1; //TrackBar位置参数
//Sobel边缘检测相关变量
Mat g_sobelGradient_X = new Mat(), g_sobelGradient_Y = new Mat();
Mat g_sobelAbsGradient_X = new Mat(), g_sobelAbsGradient_Y = new Mat();
int g_sobelKenelSize = 0; //TrackBar位置参数
//Laplace变换相关变量
int g_LaplaceKenelSize = 0; //TrackBar位置参数
//Scharr滤波器相关变量
Mat g_scharrGradient_X = new Mat(), g_scharrGradient_Y = new Mat();
Mat g_scharrAbsGradient_X = new Mat(), g_scharrAbsGradient_Y = new Mat();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//载入原图
g_srcImage = CvInvoke.Imread("girl3.jpg");
if (g_srcImage.IsEmpty)
MessageBox.Show("读取srcImage错误!");
//显示原始图
ImageBox_srcImage.Image = g_srcImage;
//显示效果图
Canny();
Sobel();
Laplace();
Scharr();
//Lable文本显示
Lable_CannyValue.Text = "阈值:" + TrackBar_CannyValue.Value.ToString();
Lable_SobelValue.Text = "核大小:" + (2 * TrackBar_SobelValue.Value + 1).ToString();
Lable_LaplaceValue.Text = "核大小:" + (2 * TrackBar_LaplaceValue.Value + 1).ToString();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape || e.KeyCode == Keys.Q)
{
MessageBox.Show("程序退出中...");
Application.Exit();
}
}
//Canny边缘检测的滚动条事件函数
private void TrackBar_CannyValue_Scroll(object sender, EventArgs e)
{
Canny();
Lable_CannyValue.Text = "阈值:" + TrackBar_CannyValue.Value.ToString();
}
//Sobel边缘检测的滚动条事件函数
private void TrackBar_SobelValue_Scroll(object sender, EventArgs e)
{
Sobel();
Lable_SobelValue.Text = "核大小:" + (2 * TrackBar_SobelValue.Value + 1).ToString();
}
//Laplacian转换的滚动条事件函数
private void TrackBar_LaplaceValue_Scroll(object sender, EventArgs e)
{
Laplace();
Lable_LaplaceValue.Text = "核大小:" + (2 * TrackBar_LaplaceValue.Value + 1).ToString();
}
//封装Canny边缘检测的函数
void Canny()
{
//原图的灰度图
Mat g_srcGrayImage = new Mat();
//将原图像转换为灰度图像
CvInvoke.CvtColor(g_srcImage, g_srcGrayImage, ColorConversion.Rgb2Gray);
//先使用3×3内核来降噪
CvInvoke.Blur(g_srcGrayImage, g_cannyDetectedEdges, new Size(3, 3), new Point(-1, -1));
//g_cannyLowThreshold赋值
g_cannyLowThreshold = TrackBar_CannyValue.Value;
//运行Canny算子
CvInvoke.Canny(g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold * 3);
//定义dstImage变量,用于存储效果图
Mat g_dstImage = new Mat();
//使用Canny算子输出的边缘图作为掩码,来将原图g_srcImage拷贝到目标图g_dstImage中
g_srcImage.CopyTo(g_dstImage, g_cannyDetectedEdges);
//显示效果图
ImageBox_cannyImage.Image = g_dstImage;
}
//封装Sobel边缘检测的函数
void Sobel()
{
//g_sobelKenelSize赋值
g_sobelKenelSize = TrackBar_SobelValue.Value;
//求X方向梯度
CvInvoke.Sobel(g_srcImage, g_sobelGradient_X, DepthType.Cv16S, 1, 0, (2 * g_sobelKenelSize + 1), 1, 1);
CvInvoke.ConvertScaleAbs(g_sobelGradient_X, g_sobelAbsGradient_X, 1, 0); //计算绝对值,并将结果转换为8位
//求Y方向梯度
CvInvoke.Sobel(g_srcImage, g_sobelGradient_Y, DepthType.Cv16S, 0, 1, (2 * g_sobelKenelSize + 1), 1, 1);
CvInvoke.ConvertScaleAbs(g_sobelGradient_Y, g_sobelAbsGradient_Y, 1, 0); //计算绝对值,并将结果转换为8位
//定义dstImage变量,用于存储效果图
Mat g_dstImage = new Mat();
//合并梯度
CvInvoke.AddWeighted(g_sobelAbsGradient_X, 0.5, g_sobelAbsGradient_Y, 0.5, 0, g_dstImage);
//显示效果图
ImageBox_sobelImage.Image = g_dstImage;
}
//封装Laplace转换的函数
void Laplace()
{
//原图的灰度图
Mat g_srcGrayImage = new Mat();
//将原图像转换为灰度图像
CvInvoke.CvtColor(g_srcImage, g_srcGrayImage, ColorConversion.Rgb2Gray);
//使用高斯滤波降噪
CvInvoke.GaussianBlur(g_srcGrayImage, g_srcGrayImage, new Size(3, 3), 0, 0);
//g_LaplaceKenelSize赋值
g_LaplaceKenelSize = TrackBar_LaplaceValue.Value;
//定义dstImage和g_dstAbsImage变量,用于存储效果图
Mat g_dstImage = new Mat(), g_dstAbsImage = new Mat();
//使用Laplace函数
CvInvoke.Laplacian(g_srcGrayImage, g_dstImage, DepthType.Cv16S, (2 * g_LaplaceKenelSize + 1));
CvInvoke.ConvertScaleAbs(g_dstImage, g_dstAbsImage, 1, 0); //计算绝对值,并将结果转换为8位
//显示效果图
ImageBox_laplaceImage.Image = g_dstAbsImage;
}
//封装Scharr边缘检测的函数
void Scharr()
{
//定义dstImage变量,用于存储效果图
Mat g_dstImage = new Mat();
//求X方向梯度
CvInvoke.Scharr(g_srcImage, g_scharrGradient_X, DepthType.Cv16S, 1, 0);
CvInvoke.ConvertScaleAbs(g_scharrGradient_X, g_scharrAbsGradient_X, 1, 0); //计算绝对值,并将结果转换为8位
//求Y方向梯度
CvInvoke.Scharr(g_srcImage, g_scharrGradient_Y, DepthType.Cv16S, 0, 1);
CvInvoke.ConvertScaleAbs(g_scharrGradient_Y, g_scharrAbsGradient_Y, 1, 0); //计算绝对值,并将结果转换为8位
//合并梯度
CvInvoke.AddWeighted(g_scharrAbsGradient_X, 0.5, g_scharrAbsGradient_Y, 0.5, 0, g_dstImage);
//显示效果图
ImageBox_scharrImage.Image = g_dstImage;
}
}
}
程序运行效果如下图所示:
如果需要完整的程序资源,可到如下链接下载: