原文: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二值图像距离变换的更多相关文章

  1. Win8Metro(C#)数字图像处理--2.24二值图像闭运算

    原文:Win8Metro(C#)数字图像处理--2.24二值图像闭运算  [函数名称] 二值图像闭运算函数CloseOperateProcess(WriteableBitmap src) [算法说 ...

  2. Win8Metro(C#)数字图像处理--2.22二值图像膨胀

    原文:Win8Metro(C#)数字图像处理--2.22二值图像膨胀  [函数名称] 二值图像膨胀函数DilationProcess(WriteableBitmap src) [算法说明]  膨胀 ...

  3. Win8Metro(C#)数字图像处理--2.23二值图像开运算

    原文:Win8Metro(C#)数字图像处理--2.23二值图像开运算  [函数名称] 二值图像开运算函数OpenOperateProcess(WriteableBitmap src) [算法说明 ...

  4. Win8Metro(C#)数字图像处理--2.21二值图像腐蚀

    原文:Win8Metro(C#)数字图像处理--2.21二值图像腐蚀  [函数名称] 二值图像腐蚀函数CorrosionProcess(WriteableBitmap src) [算法说明] 二值 ...

  5. Win8Metro(C#)数字图像处理--2.33图像非线性变换

    原文:Win8Metro(C#)数字图像处理--2.33图像非线性变换  [函数名称] 图像非线性变换函数NonlinearTransformProcess(WriteableBitmap src ...

  6. Win8Metro(C#)数字图像处理--2.40二值图像轮廓提取

    http://dongtingyueh.blog.163.com/blog/static/4619453201271481335630/ [函数名称] 二值图像轮廓提取         Contour ...

  7. Win8Metro(C#)数字图像处理--2.34直方图规定化

    原文:Win8Metro(C#)数字图像处理--2.34直方图规定化  [函数名称] WriteableBitmap HistogramSpecificateProcess(WriteableBi ...

  8. Win8Metro(C#)数字图像处理--2.30直方图均衡化

    原文:Win8Metro(C#)数字图像处理--2.30直方图均衡化 [函数名称] 直方图均衡化函数HistogramEqualProcess(WriteableBitmap src) [算法说明] ...

  9. Win8Metro(C#)数字图像处理--2.31灰度拉伸算法

    原文:Win8Metro(C#)数字图像处理--2.31灰度拉伸算法  [函数名称] 灰度拉伸函数GrayStretchProcess(WriteableBitmap src) [算法说明]    ...

随机推荐

  1. 【codeforces 546D】Soldier and Number Game

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  2. hdfs的基本原理和基本操作总结

    hdfs基本原理 Hadoop分布式文件系统(HDFS)被设计成适合执行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有非常多共同点. 但同一时候,它和 ...

  3. POJ 3714 Raid(平面近期点对)

    解题思路: 分治法求平面近期点对.点分成两部分,加个标记就好了. #include <iostream> #include <cstring> #include <cst ...

  4. Delphi 7验证XML合法性(利用DTD、XSD)

    拥有正确语法的XML被称为“形式良好”的XML.通过DTD验证的XML是“合法”的XML.DTD(文档类型定义)的作用是定义XML 文档的合法构建模块.它使用一系列的合法元素来定义文档结构.XML S ...

  5. BZOJ1010玩具装箱 - 斜率优化dp

    传送门 题目分析: 设\(f[i]\)表示装前i个玩具的花费. 列出转移方程:\[f[i] = max\{f[j] + ((i - (j + 1)) + sum[i] - sum[j] - L))^2 ...

  6. JNI基础

    1.JNI概述 JNI 是 Java Native Interface 的缩写,中文译为“Java 本地调用”.通俗的说JNI是一种技术,通过这种技术我们可以做到以下两点:  1)Java 程序中的函 ...

  7. windows 下 gcc/g++ 的安装(有图,一步一步)

    下载 mingw 首先打开 www.mingw.org .(注意版本,建议64bit) www.mingw.org 直接点击右上方的 Download Installer 即可下载. 点击 Downl ...

  8. Android中SQLite数据库操作(2)——SQLiteOpenHelper类

    如果开发者对SQL语法不熟悉,我要告诉你一个好消息,Android提供了一个SQLiteOpenHelper类. 在实际项目中很少使用SQLiteDatabase的方法(请看:http://blog. ...

  9. 双显卡安装Fedora 20

    电脑CPU上有核芯显卡,独立显卡是Nvidia的GeForce.在安装Fedora 20 64位的时候,通常会有一个优先级.在电脑BIOS中有一个显卡的启动选项,PCIe或者IGFX,PCIe是独立显 ...

  10. android延时处理任务范例

    今天要做一个任务,要求图片做button开关,点击出发对应事件.点击打开,图片左边显示几行字体,这几行字体是延时显示的.以下将主要代码附上.以下是main.xml <?xml version=& ...