Marco 发表于 2016-10-18 15:18:12

LeadTools图像处理(五)之边缘检测

本帖最后由 Marco 于 2016-10-18 15:16 编辑

在今天这篇文章中,主要想和大家分享一下图像的边缘检测。边缘检测常见的算子有Sobel, Prewitt, Laplacian等。在这里,demo主要使用的是Sobel算子,以及LeadTool提供的几种算子的Command(Sobel,Prewitt,Laplacian)。
具体步骤如下:1. 建立windows窗体应用程序,命名为Edge Detect2. 双击Form1,在Form1_Load()事件中添加如下代码:string MY_LICENSE_FILE = @"C:\LEADTOOLS 19\eval-license-files.lic";
            string MY_DicomDEVELOPER_KEY = "isxJXppTiJaYbQDDRtEzk4CRX8BJLmQI49383qJpsDProMTYamPF1yiYkXquCmFEPpyVcuuaayTRpLJGp+Gdl0sjSKF9n0ru";
            RasterSupport.SetLicense(MY_LICENSE_FILE, MY_DicomDEVELOPER_KEY);
            // Initialize a new RasterCodecs object
            codecs = new RasterCodecs();3.   打开窗体设计页面,拖入一个Image Viewer 控件,命名为the Viewer1
4.    添加与前一教程相同的引用,同时添加如下引用。并在using代码之后添加如下代码。Leadtools.ImageProcessing.Effects.dllusing Leadtools.ImageProcessing.Effects;5.   打开窗体设计模式,拖入菜单控件,添加”File”,”Function”选项,并在”Function” 选项下添加如下选项:”Sobel(Lead Tools)” , ”Sobel”,”Prewitt”,”Laplacian”
6.在Form1类中定义如下变量 private RasterCodecs codecs;
      RasterImage Image;
      bool result;
      bool back;
      int count = 0;
      RasterImage sobeloutput;7. 在Form1类中添加如下方法

      //判断是否用户已选择目标图片
      private bool checking()
      {
            if (theViewer1.Image == null)
            {
                MessageBox.Show("Please load the Image");
                return false;
            }

            else
            {
                return true;
            }
      }
      //判断是否需要重新选择图片
      private bool checkingcount()
      {
            if (count >=1)
            {
                MessageBox.Show("Please load the Image agian");
                theViewer1.Image = null;
                count = 0;
                return true;
            }
            else
            {
                return false;
            }
      }
8.在Form1类中添加如下方法private void sobelalgorithm(RasterImage inputimage)
      {
      
            //创建一个与image 大小,位深相同的图像在内存中用于存储处理之后的图像
            sobeloutput = new RasterImage(
                   RasterMemoryFlags.Conventional,
                   inputimage.Width,
                  inputimage.Height,
                  inputimage.BitsPerPixel,
                  inputimage.Order,
                  inputimage.ViewPerspective,
                  inputimage.GetPalette(),
                   IntPtr.Zero,
                   0);
            byte[]newpixel=new byte;
         //sobel 模板
            byte[] a00, a01, a02;
            byte[] a10, a11, a12;
            byte[] a20, a21, a22;
      
         for (int i = 1; i < inputimage.Height-1; i++)
         {
               for (int j = 1; j < inputimage.Width-1; j++)
               {
                   a00 =inputimage.GetPixelData(i - 1, j - 1);
                   a01 =inputimage.GetPixelData(i - 1, j );
                   a02 =inputimage.GetPixelData(i - 1, j+1);
                   a10 =inputimage.GetPixelData(i , j - 1);
                   a11 = inputimage.GetPixelData(i, j);                     //模板卷积图像
                   a12 =inputimage.GetPixelData(i, j +1);
                   a20 = inputimage.GetPixelData(i +1, j - 1);
                   a21 = inputimage.GetPixelData(i + 1, j );
                   a22 =inputimage.GetPixelData(i + 1, j+1);

                   double[] ux=new double;
                   double[] uy=new double;
                   for (int index = 0; index < 3; index++)
                   {
                     // x方向上的近似导数
                     ux = a20 * (1) + a21 * (2) + a22 * (1)
                        + (a00 * (-1) + a01 * (-2) + a02 * (-1));
                     //// y方向上的近似导数
                     uy = a02 * (1) + a12 * (2) + a22 * (1)
                     + a00 * (-1) + a10 * (-2) + a20 * (-1);
                     //x,y方向上梯度合并
                     newpixel = (byte)(Math.Sqrt(ux * ux + uy * uy));
                  
                   }
                   //
                   sobeloutput.SetPixelData(i, j, newpixel);
               }
         }

         
      }9.切换回窗体设计页面,双击”File”,在代码页面中会出现click事件,在事件中添加如下代码private void fileToolStripMenuItem_Click(object sender, EventArgs e)
      {
            theViewer1.Image = null;
            // 显示打开文件对话框
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Files|*.*";
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                try
                {
                  // 载入图像
                  Image = codecs.Load(dlg.FileName);
                  theViewer1.ItemSize=Image.ImageSize;
                  theViewer1.Image = Image;    //theViewer1控件显示原始图像

                }
                catch (Exception ex)
                {
                  MessageBox.Show(this, ex.Message);
                }
            }

      }
10.切换回窗体设计页面分别双击四个子选项,在代码页面会出现四个click事件,分别在事件中添加如下代码:Sobel (LeadTools): private void sobelLeadToollsToolStripMenuItem_Click(object sender, EventArgs e)
      {

            result = checking();
            if (result == false)
            {
                return;
            }

            back = checkingcount();
            if (back == true)
            {
                return;
            }
            count++;
   
            EdgeDetectorCommand command = new EdgeDetectorCommand();
            command.Threshold = 20;                        //选择阈值
            command.Filter = EdgeDetectorCommandType.SobelBoth;//确定边缘检测的算子
            
            command.Run(Image);
            theViewer1.Image = Image;
      }Sobel Algorithm: private void sobleToolStripMenuItem_Click(object sender, EventArgs e)
      {
            result = checking();
            if (result == false)
            {
                return;
            }

            back = checkingcount();
            if (back == true)
            {
                return;
            }
            count++;
            sobelalgorithm(Image);
            theViewer1.Image = sobeloutput;
      }
Prewitt://Prewitt(Lead Tools)
      private void prewittToolStripMenuItem_Click(object sender, EventArgs e)
      {
            result = checking();
            if (result == false)
            {
                return;
            }

            back = checkingcount();
            if (back == true)
            {
                return;
            }
            count++;
            // Prepare the command
            EdgeDetectorCommand command = new EdgeDetectorCommand();
            command.Threshold = 20;
            command.Filter = EdgeDetectorCommandType.PrewittBoth; //确定边缘检测的算子
            command.Run(Image);
            theViewer1.Image = Image;
      }
Laplacian: private void laplacianToolStripMenuItem_Click(object sender, EventArgs e)
      {
            result = checking();
            if (result == false)
            {
                return;
            }

            back = checkingcount();
            if (back == true)
            {
                return;
            }
            count++;
            // Prepare the command
            EdgeDetectorCommand command = new EdgeDetectorCommand();
            command.Threshold =15;
            command.Filter = EdgeDetectorCommandType.LaplaceVertical;//确定边缘检测的算子
            command.Run(Image);
            theViewer1.Image = Image;

      }11.生成解决方案并运行程序:结果如下:原图:
Sobel(LeadTools):
Sobel Algorithm:
Prewitt:
Laplacian:
同时附上官方文档中关于边缘检测的Command的链接以及demo的程序:https://www.leadtools.com/help/leadtools/v19/dh/to/webframe.html?platform=dotnet具体可在Image Processing ——Detecting and Enhanceing Edge and Lines 中查询具体信息。

gw0506 发表于 2016-10-19 09:21:54

这张图片已经被你玩坏了~

Marco 发表于 2016-10-19 09:36:43

gw0506 发表于 2016-10-19 09:21
这张图片已经被你玩坏了~

:lol图像处理里面比较经典的一张图片

gw0506 发表于 2016-10-19 10:53:07

Marco 发表于 2016-10-19 09:36
图像处理里面比较经典的一张图片

这个女的是谁?

Marco 发表于 2016-10-19 11:14:14

gw0506 发表于 2016-10-19 10:53
这个女的是谁?

她叫lena,据说是某一期play boy杂志的封面。因为这个图像有很多细节部分,纹理,阴影等。所以比较适合用来测试各种图像算法。

gw0506 发表于 2016-10-19 17:10:11

playboy还有这么保守的照片~~

Marco 发表于 2016-10-20 08:59:58

gw0506 发表于 2016-10-19 17:10
playboy还有这么保守的照片~~

因为这只是原图的一半;P

druidAAAA 发表于 2017-1-11 16:28:12

多谢楼主, 我想请问下, 直接调用 ocrPage.Recognize(null); 识别可以吗?
需要我再做一次边缘识别吗?
(还是你的意思是, 对于难识别的图片我还是需要自己调用多一次边缘算法, 对图像进行预加工?)

public string Read(System.IO.MemoryStream img)
      {
            // Create an OCR document
            using (IOcrDocument ocrDocument = ocrEngine.DocumentManager.CreateDocument())
            {
                img.Position = 0;
                IOcrPage ocrPage = ocrDocument.Pages.AddPage(img, null);
               
                ocrPage.Recognize(null);

                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                ocrDocument.Save(stream, DocumentFormat.Text, null);

                byte[] buff = stream.ToArray();
                string rsl = System.Text.Encoding.Default.GetString(buff);

                return rsl;
            }
页: [1]
查看完整版本: LeadTools图像处理(五)之边缘检测