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 ...
随机推荐
- lru cache java
http://www.acmerblog.com/leetcode-lru-cache-lru-5745.html acm之家的讲解是在是好,丰富 import java.util.LinkedHas ...
- ARM--存储管理器
初入领悟: 1. bank.L-bank的概念 2. s3c2440内部管理SDRAM寄存器配置 Frist part:原理分析 S3c2440为32位微处理器,其可访问空间为4G:但其中提供1G外设 ...
- 2014-5-23 s3c2440到手
( 之前的开发板是s5pv210 (contex A8)); 现在入手JZ2440......................
- hadoop-1.2.0安装记录
一.添加用户(各机器均一致) 添加组: sudo addgroup hadoop 添加用户并到组:sudo adduser -ingroup hadoop hadoop 二.ssh无验 ...
- 如何把jquery 的dialog和ztree结合
第一步:先准备好juqury-ui.ztree 的js文件和css 文件 第二步:example.jsp文件代码中写 ..引入jqueryui.ztree 的js和css文件 <body> ...
- 查看当前正在被执行的sql
由于在公司服务器上在某个时段查询某个sql执行比较慢,由来查询当前正在被执行的sql Select t.text,SUBSTRING(t.text, (r.statement_start_offset ...
- DataSet、DataTable和DataGridView知识备忘
datatable中,获取第i行j列的单元格内容: string str = DataSet.Tables[0].Rows[i][j].ToString():datagridv ...
- salt-minion安装脚本
#!/bin/bash cd /usr/local/src/ wget http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.no ...
- YUV422蓝屏显示输出功能辅助调试
YUV422蓝屏显示输出功能辅助调试 YUV422有YUYV,YVYU,UYVY,VYUY四种,以下笔者就就以UYVY为例介绍一下数据构成.因为常常要跟视频输入打交道,所以YUV422这种常见的视频信 ...
- Java SE学习之printf 日期转换符
本文是学习网络上的文章时的总结,感谢大家无私的分享. System.out.printf()方法能够对日期做处理输出. 相应列表 转换符 类型 举例 c 完整的日期和时间 Mon Feb 09 18: ...