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
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
随机推荐
- OpenVZ VPS加速方案–Final Speed
body,td { font-family: 微软雅黑; font-size: 10pt } OpenVZ VPS加速方案–Final Speed OpenVZ VPS加速方案–Final Spe ...
- MYSQL 分组排序
http://www.cnblogs.com/merru/articles/4626045.html SELECT a.shop_id, a.price, count(*) as rankFROM m ...
- Python全栈开发day8
一.python生成/迭代器 yiled生成数据 python迭代器, 访问数据(通过next一次一次去取) 二.反射 通过字符串的形式,导入模块 通过字符串的形式,到模块中,寻找指定的函数,并执行 ...
- C#与Java的比较
C#与Java的比较 写完后得知维基百科里有更加全面得多的比较: http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java NET(C#) ...
- input[file]标签的accept=”image/*”属性响应很慢的解决办法
转自:http://blog.csdn.net/lx583274568/article/details/52983693 input[file]标签的accept属性可用于指定上传文件的 MIME类型 ...
- REST 风格的api
REST即表述性状态传递,是设计风格不是标准.REST架构风格有以下6个约束: 1. 客户-服务器(Client-Server):通信只能由客户端单方面发起,表现为请求-响应形式. 2.无状态:通信的 ...
- InnoDB is limited to row-logging when transaction isolation level is READ COMMIT
分析: http://blog.csdn.net/lingli219/article/details/46372737 解决办法: http://niuzhenxin.iteye.com/blog/1 ...
- 预测帖 苹果在2年之内会换Arm
这几天看了iPad Pro和新的macbook, 我个人预测,苹果2年之内必换Arm处理器 首先会是笔记本. 而且会把软件移植也做的很好,不需要怎么改代码,只需要编译的时候加入相应的cpu就可以.至于 ...
- 【Python全栈笔记】04 [模块二] 18 Oct lambda表达式, 内置函数
lambda表达式 lambda表达式是函数的一种简化,如下面两种函数定义方法,实际上效果是一样的. 使用lambda表达式的函数,func2是函数名,lambda: 后面的123 即为返回值. de ...
- Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->Spring Framework的依赖注入和控制反转
Dependency Injection and Inversion of Control 1.概述: 1.1相关概念 bean:由IoC容器所管理的对象,也即各个类实例化所得对象都叫做bean 控制 ...