C# Susan边缘检测(Susan Edge Detection)
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)的更多相关文章
- 计算机视觉中的边缘检测Edge Detection in Computer Vision
计算机视觉中的边缘检测 边缘检测是计算机视觉中最重要的概念之一.这是一个很直观的概念,在一个图像上运行图像检测应该只输出边缘,与素描比较相似.我的目标不仅是清晰地解释边缘检测是怎样工作的,同时也提 ...
- 【数字图像分析】基于Python实现 Canny Edge Detection(Canny 边缘检测算法)
Canny 边缘检测算法 Steps: 高斯滤波平滑 计算梯度大小和方向 非极大值抑制 双阈值检测和连接 代码结构: Canny Edge Detection | Gaussian_Smoothing ...
- Image Processing and Analysis_8_Edge Detection:Edge Detection Revisited ——2004
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Edge detection using LoG
intensity梯度值分布跟图片的大小有关, 比如将一张小图片放大后会变得很模糊, 原先清晰的edge, 即大的梯度值变得模糊. 但是原有的边缘通常还是肉眼可分辨的. 但用Sobel 算子可能就检测 ...
- Image Processing and Analysis_21_Scale Space:Edge Detection and Ridge Detection with Automatic Scale Selection——1998
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Image Processing and Analysis_8_Edge Detection:Local Scale Control for Edge Detection and Blur Estimation——1998
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Image Processing and Analysis_8_Edge Detection: Optimal edge detection in two-dimensional images ——1996
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Image Processing and Analysis_8_Edge Detection:Multiresolution edge detection techniques ——1995
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Image Processing and Analysis_8_Edge Detection:Scale-space and edge detection using anisotropic diffusion——1990
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
随机推荐
- OpenSSL主配置文件openssl.cnf
虽说配置文件很多设置不用修改就能直接使用,但是了解它是配置openssl相关事项所必须的.而且要实现复杂多功能,必然要对配置相关了然于心. 1.man config 该帮助文档说明了openssl.c ...
- iOS图片编辑功能实现
图片加标签:标签可以编辑 https://github.com/shumingli/waterMark 1. 编辑效果;图片可以放到.缩小.旋转 2. 保存相册效果
- c#中实现多个接口出现同名同参的方法
IDictionary接口类同时继承了 IEnumerable<KeyValuePair<TKey, TValue>> 和 IEnumerable这两个接口 public in ...
- php+mysql
本文整理一下使用php和mysql向前端推送数据的过程. 数据库部分: 1.首先安装服务器,我选择xampp,安装可以选择任意地址.安装完成,打开xampp-control.exe . 选择开启Apa ...
- 1-12 ARP协议
ARP(Address Resolution Protocol)地址解析协议,负责将相应的IP地址解析成MAC地址. 在局域网中,网络中实际传输的是‘帧’,帧里面包含了目的主机的MAC.ARP就是用来 ...
- jquery each循环,
jquery each循环,要实现break和continue的功能: break----用return false; continue --用return ture; each()函数是基本上所有的 ...
- [转]Direct3D 11 Tessellation Tutorial
The new hardware tessellation feature available on Direct3D 11 video cards has great potential, but ...
- PPTP-VPN第一章——部署与简单使用
最近前游戏同事搞了台的VPS,贡献出来做VPN使用.目前流行的服务器VPN软件主要有PPTP VPN和Openvpn.Openvpn虽然功能较为强大,且安全性高,支持nat穿越等等,但服务器端和客户端 ...
- 让div固定在顶部不随滚动条滚动
让div固定在顶部不随滚动条滚动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...
- 记一次u盘 无法格式化、0字节、写保护的解决过程
首先各种找方法,下载了一堆烂七八糟的东西都没能解决 后来看了这个链接的文章 http://jingyan.baidu.com/article/6079ad0e5bdec428ff86dbcd.html ...