博主做的很简单,大家看一看就好了......

用到的算法是robert算子,这是一种比较简单的算法:

f(x,y)=sqrt((g(x,y)-g(x+1,y+1))^2+(g(x+1,y)-g(x,y+1))^2)

博主一共写了三段代码,第一段是边缘提取,第二段是线条加粗,第三段是原图和边缘图重合,三段代码可以放在一起,但为了看得清晰我就把他们分开了。

简单粗暴直接上代码!

private void Image_Test()
{
if (this.pBox.Image != null)
{ int Height = this.pBox.Image.Height;
int Width = this.pBox.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
Bitmap MyBitmap = (Bitmap)this.pBox.Image;
BitmapData oldData = MyBitmap.LockBits(new Rectangle(, , Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); //原图
BitmapData newData = bitmap.LockBits(new Rectangle(, , Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); //新图即边缘图
unsafe
{
//首先第一段代码是提取边缘,边缘置为黑色,其他部分置为白色
byte* pin_1 = (byte*)(oldData.Scan0.ToPointer());
byte* pin_2 = pin_1 + (oldData.Stride);
byte* pout = (byte*)(newData.Scan0.ToPointer());
for (int y = ; y < oldData.Height - ; y++)
{
for (int x = ; x < oldData.Width; x++)
{
//使用robert算子
double b = System.Math.Sqrt(((double)pin_1[] - (double)(pin_2[] + )) * ((double)pin_1[] - (double)(pin_2[] + )) + ((double)(pin_1[] + ) - (double)pin_2[]) * ((double)(pin_1[] + ) - (double)pin_2[]));
double g = System.Math.Sqrt(((double)pin_1[] - (double)(pin_2[] + )) * ((double)pin_1[] - (double)(pin_2[] + )) + ((double)(pin_1[] + ) - (double)pin_2[]) * ((double)(pin_1[] + ) - (double)pin_2[]));
double r = System.Math.Sqrt(((double)pin_1[] - (double)(pin_2[] + )) * ((double)pin_1[] - (double)(pin_2[] + )) + ((double)(pin_1[] + ) - (double)pin_2[]) * ((double)(pin_1[] + ) - (double)pin_2[]));
double bgr = b + g + r;//博主一直在纠结要不要除以3,感觉没差,选阈值的时候调整一下就好了- - if (bgr > ) //阈值,超过阈值判定为边缘(选取适当的阈值)
{
b = ;
g = ;
r = ;
}
else
{
b = ;
g = ;
r = ;
}
pout[] = (byte)(b);
pout[] = (byte)(g);
pout[] = (byte)(r);
pin_1 = pin_1 + ;
pin_2 = pin_2 + ;
pout = pout + ; }
pin_1 += oldData.Stride - oldData.Width * ;
pin_2 += oldData.Stride - oldData.Width * ;
pout += newData.Stride - newData.Width * ;
} //这里博主加粗了一下线条- -,不喜欢的同学可以删了这段代码
byte* pin_5 = (byte*)(newData.Scan0.ToPointer());
for (int y = ; y < oldData.Height - ; y++)
{
for (int x = 3; x < oldData.Width; x++)
{
if(pin_5[]==&&pin_5[]==&&pin_5[]==)
{
pin_5[-] = ;
pin_5[-] = ;
pin_5[-] = ; //边缘点的前一个像素点置为黑色(注意一定要是遍历过的像素点)
}
pin_5 += ; }
pin_5 += newData.Stride - newData.Width * ;
} //这段代码是把原图和边缘图重合
byte* pin_3= (byte*)(oldData.Scan0.ToPointer());
byte* pin_4 = (byte*)(newData.Scan0.ToPointer());
for (int y = ; y < oldData.Height - ; y++)
{
for (int x = ; x < oldData.Width; x++)
{
if (pin_4[] == && pin_4[]== && pin_4[]==)
{
pin_4[] = pin_3[];
pin_4[] = pin_3[];
pin_4[] = pin_3[];
}
pin_3 += ;
pin_4 += ;
}
pin_3 += oldData.Stride - oldData.Width * ;
pin_4 += newData.Stride - newData.Width * ;
}
//......
bitmap.UnlockBits(newData);
MyBitmap.UnlockBits(oldData);
this.pBox.Image = bitmap;
} } }

例子1:

例子2:

C# 简单的图像边缘提取的更多相关文章

  1. CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能

    CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...

  2. Python用Pillow(PIL)进行简单的图像操作

    Python用Pillow(PIL)进行简单的图像操作 颜色与RGBA值 计算机通常将图像表示为RGB值,或者再加上alpha值(通透度,透明度),称为RGBA值.在Pillow中,RGBA的值表示为 ...

  3. 四种简单的图像显著性区域特征提取方法-----AC/HC/LC/FT。

    四种简单的图像显著性区域特征提取方法-----> AC/HC/LC/FT. 分类: 图像处理 2014-08-03 12:40 4088人阅读 评论(4) 收藏 举报 salient regio ...

  4. 简单的图像显著性区域特征提取方法-----opencv实现LC,AC,FT

    https://blog.csdn.net/cai13160674275/article/details/72991049?locationNum=7&fps=1 四种简单的图像显著性区域特征 ...

  5. 基于qml创建最简单的图像处理程序(3)-使用opencv&qml进行图像处理

    <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...

  6. 基于qml创建最简单的图像处理程序(2)-使用c++&qml进行图像处理

     <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/8 ...

  7. 基于qml创建最简单的图像处理程序(1)-基于qml创建界面

    <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...

  8. Python下opencv使用笔记(二)(简单几何图像绘制)

    简单几何图像一般包含点.直线.矩阵.圆.椭圆.多边形等等.首先认识一下opencv对像素点的定义. 图像的一个像素点有1或者3个值.对灰度图像有一个灰度值,对彩色图像有3个值组成一个像素值.他们表现出 ...

  9. Win8 Metro(C#)数字图像处理--2.56简单统计法图像二值化

    原文:Win8 Metro(C#)数字图像处理--2.56简单统计法图像二值化  [函数名称] 简单统计法图像二值化 WriteableBitmap StatisticalThSegment(Wr ...

随机推荐

  1. 【解决】Django下使用sqlite3的相关问题

    最近在玩Django,想用它写一个很小很小的项目,Django自带数据库sqlite3,本来项目也小,我就用它了. 玩意虽小,东西却不是那么好用的. 首先,在项目中建立模型,一个例子是这样的: cla ...

  2. csipsimple 下载地址

    项目下载地址: http://git.oschina.net/zencodex/CSipSimple https://github.com/zencodex/csip

  3. 如何自己编译生成Eclipse插件,如hadoop-eclipse-plugin-2.2.0.jar

    如何自己编译生成Eclipse插件,如hadoop-eclipse-plugin-2.2.0.jar http://cxshun.iteye.com/blog/1876366 大数据是当今的一个热门话 ...

  4. ios:Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?

    - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)laun ...

  5. 对XML和YAML文件实现I/O操作

    1.文件的打开关闭 XML\YAML文件在OpenCV中的数据结构为FileStorage,打开操作例如: string filename = "I.xml"; FileStora ...

  6. Shiro 源码分析

    http://my.oschina.net/huangyong/blog/215153 Shiro 是一个非常优秀的开源项目,源码非常值得学习与研究. 我想尝试做一次 不一样 的源码分析:源码分析不再 ...

  7. HDU 3333 & 3874 (线段树+离线询问)

    两个题目都是求区间之内,不重复的数字之和,3333需要离散化处理................. 调试了一下午........说多了都是泪........... #include <iostr ...

  8. 理解 MEF

    1.它解决什么问题? 考虑下面的需求,甲程序员对外暴露接口,内部提供实现.乙程序员使用甲提供的接口,根据面向接口编程的原则,乙关联一个接口类型的引用.正常情况下,乙要使用甲的实现,必须实例化一个具体对 ...

  9. C++ ORM ODB 入门介绍(一)

    C++的语言特性决定了在C++中的ORM框架不可能像Java,C#那没有那么灵活. C++的ORM框架一般都是基于模板,编译时,因此其效率比起Java中的ORM框架更高. ODB是一个比较独立,成熟的 ...

  10. php加载memcache

    安装php加载memcache[root@web-server ~]# rpm -qa | grep libevent [root@web-server ~]# yum -y install libe ...