C# 简单的图像边缘提取
博主做的很简单,大家看一看就好了......
用到的算法是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# 简单的图像边缘提取的更多相关文章
- CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能
CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...
- Python用Pillow(PIL)进行简单的图像操作
Python用Pillow(PIL)进行简单的图像操作 颜色与RGBA值 计算机通常将图像表示为RGB值,或者再加上alpha值(通透度,透明度),称为RGBA值.在Pillow中,RGBA的值表示为 ...
- 四种简单的图像显著性区域特征提取方法-----AC/HC/LC/FT。
四种简单的图像显著性区域特征提取方法-----> AC/HC/LC/FT. 分类: 图像处理 2014-08-03 12:40 4088人阅读 评论(4) 收藏 举报 salient regio ...
- 简单的图像显著性区域特征提取方法-----opencv实现LC,AC,FT
https://blog.csdn.net/cai13160674275/article/details/72991049?locationNum=7&fps=1 四种简单的图像显著性区域特征 ...
- 基于qml创建最简单的图像处理程序(3)-使用opencv&qml进行图像处理
<基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...
- 基于qml创建最简单的图像处理程序(2)-使用c++&qml进行图像处理
<基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/8 ...
- 基于qml创建最简单的图像处理程序(1)-基于qml创建界面
<基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...
- Python下opencv使用笔记(二)(简单几何图像绘制)
简单几何图像一般包含点.直线.矩阵.圆.椭圆.多边形等等.首先认识一下opencv对像素点的定义. 图像的一个像素点有1或者3个值.对灰度图像有一个灰度值,对彩色图像有3个值组成一个像素值.他们表现出 ...
- Win8 Metro(C#)数字图像处理--2.56简单统计法图像二值化
原文:Win8 Metro(C#)数字图像处理--2.56简单统计法图像二值化 [函数名称] 简单统计法图像二值化 WriteableBitmap StatisticalThSegment(Wr ...
随机推荐
- HDU1075 - What Are You Talking About(Trie树)
题目大意 给定一些火星文单词以及对应的英语单词,然后给你一些火星文,要求你翻译成对应的英文 题解 第一次写Trie树! 把所有火星文单词插入到Trie树中,并且每个火星文单词结尾的节点记录相应英文单词 ...
- Recommended add-ons/plugins for Microsoft Visual Studio [closed]
SmartPaster - (FREE) Copy/Paste code generator for strings AnkhSvn - (FREE) SVN Source Control Integ ...
- hdu3681--Prison Break(TSP+二分)
好难的一道题. 题意:一个机器人要逃出监狱,每走一步消耗一点电量,初始时电量是满的.给一个n*m(n,m<=15)的字符数组代表监狱,F代表起始点,G代表补充满电量,每个G只能补充一次,Y代表开 ...
- Codeforces Round #313 (Div. 2) D.Equivalent Strings (字符串)
感觉题意不太好懂 = =# 给两个字符串 问是否等价等价的定义(满足其中一个条件):1.两个字符串相等 2.字符串均分成两个子串,子串分别等价 因为超时加了ok函数剪枝,93ms过的. #includ ...
- 检查REDO日志相关信息并生成HTML文件的脚本
生成HTML格式的文件 内容有: 检查数据库版本.REDO日志组情况, 最近20次日志切换频率检查--日志间的归档时间间隔, 这对查看数据库的IO繁忙时段 统计指定日期当天每小时的归档日志产生量--日 ...
- asp.net中为什么修改了配置文件后我们不需要重启IIS
本文转载:http://blog.itpub.net/12639172/viewspace-659819/ 大家知道,asp.net中,如果我们修改了配置文件只要把它保存之后,就会立刻反应到程序中, ...
- UML建模系列文章总结
本文转载:http://www.cnblogs.com/ywqu/tag/UML建模/ 本人总结: UML类图按照关系分为三大类:继承关系.拥有关系.整体与部分的关系. 继承关系:泛化.实现 拥有关系 ...
- cocos2d-x 卡牌翻牌效果的实现
转自:http://blog.csdn.net/yanghuiliu/article/details/9115833 这个能实现翻牌的action就是CCOrbitCamera. static CCO ...
- 【转】C++中了类继承和调用父类的构造函数方法
构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需 ...
- c#问答篇:对象与引用变量-----初学者的困惑
转自:http://www.cnblogs.com/huangyu/archive/2004/08/02/29622.html 从宏观的角度来看,对象是类的实例.比如: //定义一个名为Someone ...