Win8Metro(C#)数字图像处理--2.25二值图像距离变换
原文:Win8Metro(C#)数字图像处理--2.25二值图像距离变换
[函数名称]
二值图像距离变换函数DistanceTransformProcess(WriteableBitmap
src)
[算法说明]
二值图像的距离变换实际上就是将二值图像转换为灰度图像,在二值图像中我们将图像分为目标图像和背景图像,假设目标图像像素值为1,即为白色,背景像素为0即为黑色。在转换后的幅灰度图像中,每个连通域的各个像素点的灰度级与该像素点到其背景像素的最近距离有关。其中灰度级最大点的集合为目标图像的骨架,就是目标图像中心部分的像素的集合,灰度级反应了背景像素与目标图像边界的影响关系。用数学语言表示如下:
假设二值图像I包含一个连通域S,其中有目标O和背景B,距离图为D,则距离变换定义如下:
距离变换的具体步骤为:
1,将图像中的目标像素点分类,分为内部点,外部点和孤立点。
以中心像素的四邻域为例,如果中心像素为目标像素(值为1)且四邻域都为目标像素(值为1),则该点为内部点。如果该中心像素为目标像素,四邻域为背景像素(值为0),则该中心点为孤立点,如下图所示。除了内部点和孤立点之外的目标区域点为边界点。
6,对于孤立点保持不变。
以上的距离变换方法由于计算量大,比较耗时,因此在实际应用中,我们采用一种倒角模版算法,只需要对图像进行两次扫描就可以实现距离变换。该方法称为Chamfer倒角距离变换法。
该方法使用两个模版,分别为前向模版和后向模板,如下图所示:
计算步骤如下:
1,使用前向模板,对图像从上到下,从左到右进行扫描,模板中心0点对应的像素值如果为0则跳过,如果为1则计算模板中每个元素与其对应的像素值的和,分别为Sum1,Sum2,Sum3,Sum4,Sum5,而中心像素值为这五个和值中的最小值。
2,使用后向模板,对图像从下到上,从右到左进行扫描,方法同上。
3,一般我们使用的模板为3*3和5*5,分别如下图所示:
[函数代码]
///<summary>
///
Distance transform of binary image.
///</summary>
///<param
name="src">The source image.</param>
///<returns></returns>
publicstaticWriteableBitmap
DistanceTransformProcess(WriteableBitmap src)////25二值图像距离变换
{
if
(src !=null)
{
int
w = src.PixelWidth;
int
h = src.PixelHeight;
WriteableBitmap
expansionImage =newWriteableBitmap(w,
h);
byte[]
temp = src.PixelBuffer.ToArray();
int
t1, t2, t3, t4, t5, min = 0;
for
(int y = 0; y < h; y++)
{
for
(int x = 0; x < w * 4 - 4; x += 4)
{
if
(y == 0 || x == 0)
{
temp[x + y * w * 4] = 0;
temp[x + 1 + y * w * 4] = 0;
temp[x + 2 + y * w * 4] = 0;
}
else
{
if
(temp[x + y * w * 4] != 0)
{
t1 = temp[x - 3 + (y - 1) * w * 4] + 4;
t2 = temp[x + (y - 1) * w * 4] + 3;
t3 = temp[x + 3 + (y - 1) * w * 4] + 4;
t4 = temp[x - 3 + y * w * 4] + 3;
t5 = temp[x + y * w * 4];
min = GetMin(t1, t2, t3, t4, t5);
temp[x + y * w * 4] = (byte)min;
temp[x + 1 + y * w * 4] = (byte)min;
temp[x + 2 + y * w * 4] = (byte)min;
}
t2 = 0; t3 = 0; t4 = 0; t5 = 0; min = 0;
}
}
}
for
(int y = h - 2; y > 0; y--)
{
for
(int x = w * 4 - 4; x > 0; x -= 4)
{
if
(y == 1 || x == 3)
{
temp[x + y * w * 4] = 0;
temp[x + 1 + y * w * 4] = 0;
temp[x + 2 + y * w * 4] = 0;
}
else
{
if
(temp[x + y * w * 4] != 0)
{
t1 = temp[x - 3 + (y + 1) * w * 4] + 4;
t2 = temp[x + (y + 1) * w * 4] + 3;
t3 = temp[x + 3 + (y + 1) * w * 4] + 4;
t4 = temp[x + 3 + y * w * 4] + 3;
t5 = temp[x + y * w * 4];
min = GetMin(t1, t2, t3, t4, t5);
temp[x + y * w * 4] = (byte)min;
temp[x + 1 + y * w * 4] = (byte)min;
temp[x + 2 + y * w * 4] = (byte)min;
}
t2 = 0; t3 = 0; t4 = 0; t5 = 0; min = 0;
}
}
}
Stream
sTemp = expansionImage.PixelBuffer.AsStream();
sTemp.Seek(0,
SeekOrigin.Begin);
sTemp.Write(temp, 0, w * 4 * h);
return
expansionImage;
}
else
{
returnnull;
}
}
privatestaticint
GetMin(int a,
int b,int
c,int d,int
e)
{
int
t = (a < b ? a : b) < c ? (a < b ? a : b) : c;
return
((t < d ? t : d) < e ? (t < d ? t : d) : e);
}
[图像效果]
Win8Metro(C#)数字图像处理--2.25二值图像距离变换的更多相关文章
- Win8Metro(C#)数字图像处理--2.24二值图像闭运算
原文:Win8Metro(C#)数字图像处理--2.24二值图像闭运算 [函数名称] 二值图像闭运算函数CloseOperateProcess(WriteableBitmap src) [算法说 ...
- Win8Metro(C#)数字图像处理--2.22二值图像膨胀
原文:Win8Metro(C#)数字图像处理--2.22二值图像膨胀 [函数名称] 二值图像膨胀函数DilationProcess(WriteableBitmap src) [算法说明] 膨胀 ...
- Win8Metro(C#)数字图像处理--2.23二值图像开运算
原文:Win8Metro(C#)数字图像处理--2.23二值图像开运算 [函数名称] 二值图像开运算函数OpenOperateProcess(WriteableBitmap src) [算法说明 ...
- Win8Metro(C#)数字图像处理--2.21二值图像腐蚀
原文:Win8Metro(C#)数字图像处理--2.21二值图像腐蚀 [函数名称] 二值图像腐蚀函数CorrosionProcess(WriteableBitmap src) [算法说明] 二值 ...
- Win8Metro(C#)数字图像处理--2.33图像非线性变换
原文:Win8Metro(C#)数字图像处理--2.33图像非线性变换 [函数名称] 图像非线性变换函数NonlinearTransformProcess(WriteableBitmap src ...
- Win8Metro(C#)数字图像处理--2.40二值图像轮廓提取
http://dongtingyueh.blog.163.com/blog/static/4619453201271481335630/ [函数名称] 二值图像轮廓提取 Contour ...
- Win8Metro(C#)数字图像处理--2.34直方图规定化
原文:Win8Metro(C#)数字图像处理--2.34直方图规定化 [函数名称] WriteableBitmap HistogramSpecificateProcess(WriteableBi ...
- Win8Metro(C#)数字图像处理--2.30直方图均衡化
原文:Win8Metro(C#)数字图像处理--2.30直方图均衡化 [函数名称] 直方图均衡化函数HistogramEqualProcess(WriteableBitmap src) [算法说明] ...
- Win8Metro(C#)数字图像处理--2.31灰度拉伸算法
原文:Win8Metro(C#)数字图像处理--2.31灰度拉伸算法 [函数名称] 灰度拉伸函数GrayStretchProcess(WriteableBitmap src) [算法说明] ...
随机推荐
- 【社交分享SDK】ShareSDK for Android 2.5.9已经公布
ShareSDK for Android 2.5.9已经公布 版本号:V2.5.9 2015-3-19 1.升级Dropbox对API接口的调用.包含授权.获取用户信息,分享三个接口 2.升级Kak ...
- 【hdu 1517】A Multiplication Game
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
- 【u225】最优分解方案
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 经过第一轮的游戏,不少同学将会获得圣诞特别礼物,但这时细心的数学课代表发现了一个问题: 留下来的人太多 ...
- 跟上 Java 8 – 了解 lambda
原文出处: 王爵nice 从java8出现以来lambda是最重要的特性之一,它可以让我们用简洁流畅的代码完成一个功能. 很长一段时间java被吐槽是冗余和缺乏函数式编程能力的语言,随着函数式编程的流 ...
- 移动端iPhone系列适配问题的一些坑
完成移动端的开发项目之后,发现谷歌自带的调试器似乎没有什么太大的作用,整天借同事的苹果手机测bug,尽管同事不厌其烦,但还是觉得这iPhone系列适配问题适配到想逃逃逃,好在项目已经顺利完成,测试通过 ...
- 【codeforces 765B】Code obfuscation
[题目链接]:http://codeforces.com/contest/765/problem/B [题意] 让你把每个变量都依次替换成a,b,c,-.d这些字母; 且要按顺序先用a再用b-.c.d ...
- eclipse 编写scala代码时提示computing additional info
window->proference,把方框中那两个选项去掉不选,保存即可(或者只选择scala completions(java sources)),(只不过这么做之后就没有代码提示了)遇到这 ...
- 【BZOJ 1028】[JSOI2007]麻将
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1028 [题意] [题解] /* 枚举新加入的一张牌是哪一张牌; 然后尝试把它加进去; ...
- spark cogroup算子
java /** *cogroup与join算子不同的是如果rdd中的一个key,对应多个value,则返回<Iterable<key>,Iterable<value>& ...
- react持续记录零散笔记
根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff 这些生命周期在深入项目开发阶段是非常重要的 ...