Susan边缘检测,方法简单,效率高,具体参照 The SUSAN Edge Detector in Detail, 修改dThreshold值,可以改变检测效果,用参照提供的重心法、力矩法可得到边缘方向;

        /// https://users.fmrib.ox.ac.uk/~steve/susan/susan/node6.html
public unsafe static Bitmap SusanGray(this Bitmap sourceBitmap)
{
int[] rowRadius = new int[] { , , , , , , };
int width = sourceBitmap.Width;
int height = sourceBitmap.Height;
BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(, , width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int stride = sourceData.Stride;
byte[] pixelBuffer = new byte[stride * sourceData.Height];
byte[] resultBuffer = new byte[stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, , pixelBuffer.Length);
sourceBitmap.UnlockBits(sourceData); float rgb = ; for (int k = ; k < pixelBuffer.Length; k += )
{
rgb = pixelBuffer[k] * 0.11f;
rgb += pixelBuffer[k + ] * 0.59f;
rgb += pixelBuffer[k + ] * 0.3f; pixelBuffer[k] = (byte)rgb;
pixelBuffer[k + ] = pixelBuffer[k];
pixelBuffer[k + ] = pixelBuffer[k];
pixelBuffer[k + ] = ;
} int[] susanMap = new int[height * width]; int offset = stride - width * ; GCHandle srchandle = GCHandle.Alloc(susanMap, GCHandleType.Pinned);
IntPtr susan = srchandle.AddrOfPinnedObject(); int dThreshold = ;
fixed (byte* pbuff = pixelBuffer, rbuff = resultBuffer)
{
byte* src = pbuff + stride * + * ;
int* br = (int*)susan + height * + ;
byte* dst = rbuff + stride * + * ; for (int offsetY = ; offsetY < height - ; offsetY++)
{
for (int offsetX = ; offsetX < width - ; offsetX++, src += ,dst+=, br++)
{
byte nucleusValue = *src;
int usan = ; int cx = , cy = ; for (int i = -; i <= ; i++)
{ int r = rowRadius[i + ]; byte* ptr = (byte*)((int)src + stride * i); for (int j = -r; j <= r; j++)
{
int c = (int)Math.Exp(-Math.Pow((System.Math.Abs(nucleusValue - ptr[j * ]) / dThreshold), ));
usan += c;
cx += j * c;
cy += i * c;
}
}
if (usan < )
usan = -usan;
else
usan = ;
if ((usan < ) && (cx != || cy != ))
{
*dst = ;
dst[] = ;
dst[] = ;
dst[] = ;
}
else
{
*dst = ;
dst[] = ;
dst[] = ;
dst[] = ;
}
*br = usan;
}
src += * + offset;
dst += * + offset;
br += ;
}
} Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(, ,
resultBitmap.Width, resultBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, , resultData.Scan0, resultBuffer.Length);
resultBitmap.UnlockBits(resultData); return resultBitmap; }

并行的方法:

        public unsafe static Bitmap ParallelSusan(this Bitmap sourceBitmap)
{
int width = sourceBitmap.Width;
int height = sourceBitmap.Height;
BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(, , width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int stride = sourceData.Stride;
byte[] pixelBuffer = new byte[stride * sourceData.Height];
byte[] resultBuffer = new byte[stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, , pixelBuffer.Length);
sourceBitmap.UnlockBits(sourceData); float rgb = ; for (int k = ; k < pixelBuffer.Length; k += )
{
rgb = pixelBuffer[k] * 0.11f;
rgb += pixelBuffer[k + ] * 0.59f;
rgb += pixelBuffer[k + ] * 0.3f; pixelBuffer[k] = (byte)rgb;
pixelBuffer[k + ] = pixelBuffer[k];
pixelBuffer[k + ] = pixelBuffer[k];
pixelBuffer[k + ] = ;
} int[] susanMap = new int[height * width]; int offset = stride - width * ;
GCHandle srchandle = GCHandle.Alloc(pixelBuffer, GCHandleType.Pinned);
IntPtr src = srchandle.AddrOfPinnedObject(); GCHandle dsthandle = GCHandle.Alloc(resultBuffer, GCHandleType.Pinned);
IntPtr dst = dsthandle.AddrOfPinnedObject(); GCHandle suhandle = GCHandle.Alloc(susanMap, GCHandleType.Pinned);
IntPtr susan = suhandle.AddrOfPinnedObject(); System.Threading.Tasks.Parallel.For(, height - , (offsetY) =>
{
for (int offsetX = ; offsetX < width - ; offsetX++)
{
OneSusan(offsetY, offsetX, (byte*)src, (byte*)dst, stride);
}
}); Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(, ,
resultBitmap.Width, resultBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, , resultData.Scan0, resultBuffer.Length);
resultBitmap.UnlockBits(resultData); return resultBitmap; }
public unsafe static void OneSusan(int offsetY, int offsetX, byte* src, byte* dst, int stride)
{
int[] rowRadius = new int[] { , , , , , , };
int dThreshold = ; src = (byte*)((int)src + stride * offsetY + offsetX * );
dst = (byte*)((int)dst + stride * offsetY + offsetX * );
byte nucleusValue = *src;
int usan = ; int cx = , cy = ;
float vX = , vY = , vXY = ;
for (int i = -; i <= ; i++)
{ int r = rowRadius[i + ]; byte* ptr = (byte*)((int)src + stride * i); for (int j = -r; j <= r; j++)
{
int c = (int)Math.Exp(-Math.Pow((System.Math.Abs(nucleusValue - ptr[j * ]) / dThreshold), ));
usan += c;
cx += j * c;
cy += i * c;
vX += j * j * c;
vY += i * i * c;
vXY += i * j * c;
}
}
if (usan < )
usan = - usan;
else
usan = ;
if ((usan < ) && (cx != || cy != ))
{
*dst = ;
dst[] = ;
dst[] = ;
dst[] = ;
}
else
{
*dst = ;
dst[] = ;
dst[] = ;
dst[] = ;
}
}

示例下载(除Susan 方法之外的代码来自https://softwarebydefault.com/2013/05/11/image-edge-detection/)

C# Susan边缘检测(Susan Edge Detection)的更多相关文章

  1. 计算机视觉中的边缘检测Edge Detection in Computer Vision

    计算机视觉中的边缘检测   边缘检测是计算机视觉中最重要的概念之一.这是一个很直观的概念,在一个图像上运行图像检测应该只输出边缘,与素描比较相似.我的目标不仅是清晰地解释边缘检测是怎样工作的,同时也提 ...

  2. 【数字图像分析】基于Python实现 Canny Edge Detection(Canny 边缘检测算法)

    Canny 边缘检测算法 Steps: 高斯滤波平滑 计算梯度大小和方向 非极大值抑制 双阈值检测和连接 代码结构: Canny Edge Detection | Gaussian_Smoothing ...

  3. Image Processing and Analysis_8_Edge Detection:Edge Detection Revisited ——2004

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  4. Edge detection using LoG

    intensity梯度值分布跟图片的大小有关, 比如将一张小图片放大后会变得很模糊, 原先清晰的edge, 即大的梯度值变得模糊. 但是原有的边缘通常还是肉眼可分辨的. 但用Sobel 算子可能就检测 ...

  5. Image Processing and Analysis_21_Scale Space:Edge Detection and Ridge Detection with Automatic Scale Selection——1998

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  6. Image Processing and Analysis_8_Edge Detection:Local Scale Control for Edge Detection and Blur Estimation——1998

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  7. Image Processing and Analysis_8_Edge Detection: Optimal edge detection in two-dimensional images ——1996

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  8. Image Processing and Analysis_8_Edge Detection:Multiresolution edge detection techniques ——1995

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  9. Image Processing and Analysis_8_Edge Detection:Scale-space and edge detection using anisotropic diffusion——1990

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

随机推荐

  1. ubuntu 配置nginx+php+mysql 遇到的一些问题

    /* 公司内网打算配置一台ubuntu为主机的测试服务器.刚好手头有一个昂达的主机,装的windows 声音又大,还不如直接装ubuntu .声音又小,还占用资源少. */ 刚开始安装php5 结果提 ...

  2. localstorage sessionstorage cookie 备忘

    /* sessionStorage: 保存的数据用于浏览器的一次会话,当会话结束(通常是该窗口关闭),数据被清空: localStorage: 保存的数据长期存在,下一次访问该网站的时候,网页可以直接 ...

  3. [Tomcat 源码分析系列] (一) : Tomcat 启动脚本-startup.bat

    概述 我们通常使用 Tomcat 中的 startup.bat 来启动 Tomcat. 但是这其中干了一些什么事呢? 大家都知道一个 Java 程序需要启动的话, 肯定需要 main 方法, 那么这个 ...

  4. 第一个PHP程序-HelloWorld

    <?php //echo输出字符串 echo "Hello php!你好 php" ; 以上程序输出结果为:Hello php!你好 php

  5. OLE/COM 对象查看器 & OLE常用术语

    "OLE/COM Object Viewer"(OLE/COM 对象查看器)查看你系统上安装的所有 COM 对象时,是一个非常便利的工具. 它是 Windows 2000 资源套件 ...

  6. ndoutils2.2.0(ndo2db)中文乱码问题解决

    ndoutils插入中文时,产生数据库乱码请用下面两个文件: 适用版本:ndoutils-2.0.0 数据库初始化mysql.sql: 修改ndoutils-2.0.0/src目录中的db.c ndo ...

  7. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  8. Servlet学习一

    Servlet担当着客户请求(Web浏览器或其它HTTP客户程序)与服务器响应(HTTP服务器上数据库或应用程序)的中间层.Servlet是位于Web服务器内部的服务器端Java应用程序,与传统的从命 ...

  9. 团队编程——web应用之人事管理系统

    本次作业为团队作业,团队博客要求如下:1. 介绍团队情况:包括队长.成员.队名.成员照片.队训--.等:2. 介绍团队项目名称.总体任务,各成员任务等:3. 每个队做 一次需求调研(针对团队项目),要 ...

  10. 国内npm镜像源推荐及使用

    NPM(Node Package Manager),是NodeJs的模块依赖管理工具.由于Npm源在国外,使用起来不方便, 故需要国内可靠的npm源可以使用,现整理如下: 一.国内镜像 1.淘宝NPM ...