Emgu图像通道分割、阈值处理、形态学滤波

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_33442459/article/details/79563117

有如下所示图一,现在只要求标注出其中水平横线,用Emgu中图像处理方法对该图片进行操作得到图二


                                                                                图一


                                                                                   图二

一、首先在窗体中设置一个BUTTON按钮,点击按钮可以从对话框中选择需要处理的图像

Image<Bgr, Byte> Src_Image = new Image<Bgr, byte>(Openfile.FileName);

二、第二步对原始图像进行通道分离,将多通道图像变成单通道图像

CvInvoke.Split(Src_Image,vm);//分割图像B,G,R 
var vms = vm.GetOutputArray();
Mat one_channel1 = vms.GetMat(0);//B
Mat one_channel2 = vms.GetMat(1);//G
Mat one_channel3 = vms.GetMat(2);//R

三、用R通道-B通道

Image<Bgr,Byte> sub_channel = (one_channelR.ToImage<Bgr, Byte>()).Sub(one_channelB.ToImage<Bgr, Byte>());

四、高斯滤波

CvInvoke.GaussianBlur(sub_channel, sub_channel, new System.Drawing.Size(9, 9), 0, 0);

五、Otsu二值化图像

CvInvoke.Threshold(gray_image, gthreshImage, 0, 255, Emgu.CV.CvEnum.ThresholdType.Otsu);

六、矩形腐蚀

CvInvoke.Erode(gthreshImage, gthreshImage, element, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new Emgu.CV.Structure.MCvScalar(0));

七、测试函数,计算执行一次图像处理操作需要的时间

Stopwatch sw = new Stopwatch();
sw.Start();
//
代码块
//
sw.Stop();
Console.WriteLine("花费时间:" + sw.ElapsedMilliseconds + "ms");//毫秒

附上源码:

using System;
using System.Drawing;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using System.Diagnostics;

namespace WindowsFormsApp4
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			OpenFileDialog Openfile = new OpenFileDialog();
			if (Openfile.ShowDialog() == DialogResult.OK)
			{
				Image<Bgr, Byte> Src_Image = new Image<Bgr, byte>(Openfile.FileName);
				pictureBox1.Image = Src_Image.ToBitmap(); // 1、pictureBox1 显示原图
				VectorOfMat vm = new VectorOfMat();
				/**********************************测试时间Start******************************************************/
				//测试时间:原图加载过后经过一系列处理最终显示在窗口上的时间:Average Time = 65ms
				Stopwatch sw = new Stopwatch();
				sw.Start();
				//这个函数执行后的结果是单通道图片,显示出来是灰度图
				CvInvoke.Split(Src_Image,vm);//分割图像B,G,R 
				var vms = vm.GetOutputArray();
				Mat one_channelB = vms.GetMat(0);
				Mat one_channelG = vms.GetMat(1);
				Mat one_channelR = vms.GetMat(2);
				pictureBox2.Image = one_channelB.ToImage<Bgr,Byte>().ToBitmap(); // 1、pictureBox2 显示单通道B
				pictureBox3.Image = one_channelG.ToImage<Bgr, Byte>().ToBitmap(); // 1、pictureBox3 显示单通道G
				pictureBox4.Image = one_channelR.ToImage<Bgr, Byte>().ToBitmap(); // 1、pictureBox4 显示单通道R
				//R-B
				Image<Bgr,Byte> sub_channel = (one_channelR.ToImage<Bgr, Byte>()).Sub(one_channelB.ToImage<Bgr, Byte>());
				//高斯滤波
				CvInvoke.GaussianBlur(sub_channel, sub_channel, new System.Drawing.Size(9, 9), 0, 0);
				//Otsu二值化
				Image<Gray, byte> gray_image = sub_channel.Convert<Gray, byte>();
				var gthreshImage = gray_image.CopyBlank();
				//第一个参数必须是单通道灰度图,第二个参数是单通道黑白图
				CvInvoke.Threshold(gray_image, gthreshImage, 0, 255, Emgu.CV.CvEnum.ThresholdType.Otsu);
				pictureBox5.Image = gthreshImage.ToBitmap();
				//矩形腐蚀
				
				Mat element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new Size(21, 1), new Point(-1, -1));
				CvInvoke.Erode(gthreshImage, gthreshImage, element, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new Emgu.CV.Structure.MCvScalar(0));
				pictureBox5.Image = gthreshImage.ToBitmap();
				sw.Stop();
				Console.WriteLine("花费时间:" + sw.ElapsedMilliseconds + "ms");//毫秒
				/*******************************测试时间结束Stop****************************************************/
			}
		}
	}
}

注:此文章为作者原创,转载请注明出处!














猜你喜欢

转载自blog.csdn.net/sinat_33442459/article/details/79563117