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
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
随机推荐
- 利用jQuery内置的data()方法存储数据
jQuery提供了内置的data()方法,与DOM元素不同的是,它可以用来存储key/value类型的数据.数据的存储是很容易的: $('#myDiv').data('currentState', ' ...
- touches, targetTouches, changedTouches 区别
1. touches: A list of information for every finger currently touching the screen2. targetTouches: Li ...
- offer
八月份仿真实验室国赛以后,我并没有开始做一些关于找工作的准备,而是在做自己感兴趣的cocos2d-x,大概花了一个星期的时间从安装平台到查资料写了一个flappybird小游戏,将近开学了才把找工作的 ...
- Shell 的变量功能
搜寻路径PATH(系统预设变量) 执行命令时,系统透过PATH得路径顺序搜寻指令,如果再搜寻完后还找不到该指令,就会打印错误讯息[command not fount]. 环境变量 进入shell之 ...
- MVC使用内建的Form辅助器方法创建Select元素
第一种方法: List<SelectListItem> statusItems = new List<SelectListItem>(); statusI ...
- js获取及判断按键的方法
js 里面的键盘事件经常用到,所以收集了键盘事件对应的键码来分享下: keyCode 8 = BackSpace BackSpace keyCode 9 = Tab Tab keyCode 12 = ...
- MacOS清除管理员密码
1.重启 mac ,按住 Command + s 键,进入当用户模式,直达出现黑底白字的屏幕,再松开.输入(重新挂载根文件系统为可读写):mount -uw / 2.然后输入:rm /var/db/. ...
- avi文件打开出现花屏、打开不了问题
以avi为后缀名文件,其编码格式并不是单一的,而是多种格式都可以以avi作为后缀. AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchang ...
- StringBuilder类型
一.概念 String对象时不可变的,每次使用String类中的一个方法时,都要在内存中创建一个新的字符串对象,这就需要为该对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的String ...
- http 错误 500.21
出现这个错误一般都是.net Framework 在iis中安装错误 这个时候需要重新安装iis .netframework 4.0框架 我的解决方案如下: 在cmd中以管理员身份运行->%wi ...