找回密码
 立即注册

QQ登录

只需一步,快速开始

Marco

中级会员

6

主题

11

帖子

832

积分

中级会员

积分
832
Marco
中级会员   /  发表于:2016-10-18 15:18  /   查看:5699  /  回复:7
本帖最后由 Marco 于 2016-10-18 15:16 编辑

在今天这篇文章中,主要想和大家分享一下图像的边缘检测。边缘检测常见的算子有Sobel, Prewitt, Laplacian等。在这里,demo主要使用的是Sobel算子,以及LeadTool提供的几种算子的Command(Sobel,Prewitt,Laplacian)。

具体步骤如下:
1. 建立windows窗体应用程序,命名为Edge Detect
2. 双击Form1,在Form1_Load()事件中添加如下代码:
  1. string MY_LICENSE_FILE = @"C:\LEADTOOLS 19\eval-license-files.lic";
  2.             string MY_DicomDEVELOPER_KEY = "isxJXppTiJaYbQDDRtEzk4CRX8BJLmQI49383qJpsDProMTYamPF1yiYkXquCmFEPpyVcuuaayTRpLJGp+Gdl0sjSKF9n0ru";
  3.             RasterSupport.SetLicense(MY_LICENSE_FILE, MY_DicomDEVELOPER_KEY);
  4.             // Initialize a new RasterCodecs object
  5.             codecs = new RasterCodecs();
复制代码
3.   打开窗体设计页面,拖入一个Image Viewer 控件,命名为the Viewer1

4.    添加与前一教程相同的引用,同时添加如下引用。并在using代码之后添加如下代码。
  1. Leadtools.ImageProcessing.Effects.dll
复制代码
  1. using Leadtools.ImageProcessing.Effects;
复制代码
5.   打开窗体设计模式,拖入菜单控件,添加”File”,”Function”选项,并在”Function” 选项下添加如下选项:”Sobel(Lead Tools)” , ”Sobel”,”Prewitt”,”Laplacian”

6.  在Form1类中定义如下变量
  1. private RasterCodecs codecs;
  2.         RasterImage Image;
  3.         bool result;
  4.         bool back;
  5.         int count = 0;
  6.         RasterImage sobeloutput;
复制代码
7. 在Form1类中添加如下方法


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

  9.             else
  10.             {
  11.                 return true;
  12.             }
  13.         }
  14.         //判断是否需要重新选择图片
  15.         private bool checkingcount()
  16.         {
  17.             if (count >=1)
  18.             {
  19.                 MessageBox.Show("Please load the Image agian");
  20.                 theViewer1.Image = null;
  21.                 count = 0;
  22.                 return true;
  23.             }
  24.             else
  25.             {
  26.                 return false;
  27.             }
  28.         }
复制代码
8.  在Form1类中添加如下方法
  1. private void sobelalgorithm(RasterImage inputimage)
  2.         {
  3.         
  4.             //创建一个与image 大小,位深相同的图像在内存中用于存储处理之后的图像
  5.             sobeloutput = new RasterImage(
  6.                    RasterMemoryFlags.Conventional,
  7.                    inputimage.Width,
  8.                     inputimage.Height,
  9.                     inputimage.BitsPerPixel,
  10.                     inputimage.Order,
  11.                     inputimage.ViewPerspective,
  12.                     inputimage.GetPalette(),
  13.                    IntPtr.Zero,
  14.                    0);
  15.             byte[]newpixel=new byte[3];
  16.            //sobel 模板
  17.               byte[] a00, a01, a02;
  18.               byte[] a10, a11, a12;
  19.               byte[] a20, a21, a22;
  20.         
  21.            for (int i = 1; i < inputimage.Height-1; i++)
  22.            {
  23.                for (int j = 1; j < inputimage.Width-1; j++)
  24.                {
  25.                    a00 =inputimage.GetPixelData(i - 1, j - 1);
  26.                    a01 =  inputimage.GetPixelData(i - 1, j );
  27.                    a02 =  inputimage.GetPixelData(i - 1, j+1);
  28.                    a10 =  inputimage.GetPixelData(i , j - 1);
  29.                    a11 = inputimage.GetPixelData(i, j);                       //模板卷积图像
  30.                    a12 =  inputimage.GetPixelData(i, j +1);
  31.                    a20 = inputimage.GetPixelData(i +1, j - 1);
  32.                    a21 = inputimage.GetPixelData(i + 1, j );
  33.                    a22 =  inputimage.GetPixelData(i + 1, j+1);
  34.   
  35.                    double[] ux=new double[3];
  36.                    double[] uy=new double[3];
  37.                    for (int index = 0; index < 3; index++)
  38.                    {  
  39.                        // x方向上的近似导数
  40.                        ux[index] = a20[0] * (1) + a21[0] * (2) + a22[0] * (1)
  41.                         + (a00[0] * (-1) + a01[0] * (-2) + a02[0] * (-1));
  42.                        //// y方向上的近似导数
  43.                        uy[index] = a02[0] * (1) + a12[0] * (2) + a22[0] * (1)
  44.                        + a00[0] * (-1) + a10[0] * (-2) + a20[0] * (-1);
  45.                        //x,y方向上梯度合并
  46.                        newpixel[index] = (byte)(Math.Sqrt(ux[index] * ux[index] + uy[index] * uy[index]));
  47.                     
  48.                    }
  49.                    //
  50.                    sobeloutput.SetPixelData(i, j, newpixel);
  51.                }
  52.            }

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

  15.                 }
  16.                 catch (Exception ex)
  17.                 {
  18.                     MessageBox.Show(this, ex.Message);
  19.                 }
  20.             }

  21.         }
复制代码

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

  3.             result = checking();
  4.             if (result == false)
  5.             {
  6.                 return;
  7.             }

  8.             back = checkingcount();
  9.             if (back == true)
  10.             {
  11.                 return;
  12.             }
  13.             count++;
  14.    
  15.             EdgeDetectorCommand command = new EdgeDetectorCommand();
  16.             command.Threshold = 20;                          //选择阈值
  17.             command.Filter = EdgeDetectorCommandType.SobelBoth;//确定边缘检测的算子
  18.             
  19.             command.Run(Image);
  20.             theViewer1.Image = Image;
  21.         }
复制代码
Sobel Algorithm:
  1. private void sobleToolStripMenuItem_Click(object sender, EventArgs e)
  2.         {
  3.             result = checking();
  4.             if (result == false)
  5.             {
  6.                 return;
  7.             }

  8.             back = checkingcount();
  9.             if (back == true)
  10.             {
  11.                 return;
  12.             }
  13.             count++;
  14.             sobelalgorithm(Image);
  15.             theViewer1.Image = sobeloutput;
  16.         }
复制代码

Prewitt:
  1. //Prewitt(Lead Tools)
  2.         private void prewittToolStripMenuItem_Click(object sender, EventArgs e)
  3.         {
  4.               result = checking();
  5.             if (result == false)
  6.             {
  7.                 return;
  8.             }

  9.             back = checkingcount();
  10.             if (back == true)
  11.             {
  12.                 return;
  13.             }
  14.             count++;
  15.             // Prepare the command
  16.             EdgeDetectorCommand command = new EdgeDetectorCommand();
  17.             command.Threshold = 20;
  18.             command.Filter = EdgeDetectorCommandType.PrewittBoth; //确定边缘检测的算子
  19.             command.Run(Image);
  20.             theViewer1.Image = Image;
  21.         }
复制代码
Laplacian:
  1. private void laplacianToolStripMenuItem_Click(object sender, EventArgs e)
  2.         {
  3.             result = checking();
  4.             if (result == false)
  5.             {
  6.                 return;
  7.             }

  8.             back = checkingcount();
  9.             if (back == true)
  10.             {
  11.                 return;
  12.             }
  13.             count++;
  14.             // Prepare the command
  15.             EdgeDetectorCommand command = new EdgeDetectorCommand();
  16.             command.Threshold =15;
  17.             command.Filter = EdgeDetectorCommandType.LaplaceVertical;  //确定边缘检测的算子
  18.             command.Run(Image);
  19.             theViewer1.Image = Image;

  20.         }
复制代码
11.生成解决方案并运行程序:
结果如下:
原图:

Sobel(LeadTools):

Sobel Algorithm:

Prewitt:

Laplacian:

同时附上官方文档中关于边缘检测的Command的链接以及demo的程序:
具体可在Image Processing ——Detecting and Enhanceing Edge and Lines 中查询具体信息。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

评分

参与人数 1金币 +1000 收起 理由
gw0506 + 1000 很给力!

查看全部评分

7 个回复

倒序浏览
gw0506
超级版主   /  发表于:2016-10-19 09:21:54
沙发
这张图片已经被你玩坏了~
回复 使用道具 举报
Marco
中级会员   /  发表于:2016-10-19 09:36:43
板凳
gw0506 发表于 2016-10-19 09:21
这张图片已经被你玩坏了~

图像处理里面比较经典的一张图片
回复 使用道具 举报
gw0506
超级版主   /  发表于:2016-10-19 10:53:07
地板
Marco 发表于 2016-10-19 09:36
图像处理里面比较经典的一张图片

这个女的是谁?
回复 使用道具 举报
Marco
中级会员   /  发表于:2016-10-19 11:14:14
5#
gw0506 发表于 2016-10-19 10:53
这个女的是谁?

她叫lena,据说是某一期play boy杂志的封面。因为这个图像有很多细节部分,纹理,阴影等。所以比较适合用来测试各种图像算法。
回复 使用道具 举报
gw0506
超级版主   /  发表于:2016-10-19 17:10:11
6#
playboy还有这么保守的照片~~  
回复 使用道具 举报
Marco
中级会员   /  发表于:2016-10-20 08:59:58
7#
gw0506 发表于 2016-10-19 17:10
playboy还有这么保守的照片~~

因为这只是原图的一半
回复 使用道具 举报
druidAAAA
注册会员   /  发表于:2017-1-11 16:28:12
8#
多谢楼主, 我想请问下, 直接调用 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;
            }
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部