Win8 Metro(C#)數字圖像處理--2.49Zhang二值圖像細化算法

原文: Win8 Metro(C#)數字圖像處理--2.49Zhang二值圖像細化算法



[函數名稱]html

  二值圖像細化算法      WriteableBitmap ThinningProcess(WriteableBitmap src)算法

[算法說明]函數

  圖像細化(Image Thinning),通常指二值圖像的骨架化(Image Skeletonization)的一種操做運算。spa

所謂的細化就是通過一層層的剝離,從原來的圖中去掉一些點,但仍要保持原來的形狀,直到獲得圖.net

像的骨架。骨架,能夠理解爲圖象的中軸。code

  細化算法有不少,咱們這裏介紹一種二值圖像的快速細化算法Zhang 細化算法,該算法是Zhanghtm

1984年提出。blog

  算法過程以下:get

  1,設二值圖像中0爲背景,1爲目標。目標像素的8鄰域以下圖所示:it

/// <summary>
        /// Zhang's fast thinning process for binary image.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static WriteableBitmap ThinningProcess(WriteableBitmap src)////二值圖像細化(Zhang快速細化算法)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                byte[] tempMask = (byte[])temp.Clone();
                int[,] srcBytes = new int[w, h];
                for (int j = 0; j < h; j++)
                {
                    for (int i = 0; i < w ; i++)
                    {
                        srcBytes[i, j] = (tempMask[i * 4 + j * w * 4] * 0.114 + tempMask[i * 4 + 1 + j * w * 4] * 0.587 + tempMask[i * 4 + 2 + j * w * 4] * 0.299 < 128 ? 0 : 1);
                    }
                }
                Thinning(ref srcBytes, w, h);
                for (int j = 0; j < h; j++)
                {
                    for (int i = 0; i < w; i++)
                    {
                        temp[i * 4 + j * w * 4] = temp[i * 4 + 1 + j * w * 4] = temp[i * 4 + 2 + j * w * 4] = (byte)(srcBytes[i, j] * 255);
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return srcImage;
            }
            else
            {
                return null;
            }
        }
        private static void Thinning(ref int[,] srcBytes,int w,int h)
        {
            int[] srcTemp;
            int countNumber;
            do
            {
                countNumber = 0;
                for (int y = 1; y < h - 1; y++)
                {
                    for (int x = 1; x < w - 1; x++)
                    {
                        srcTemp = new int[9] { srcBytes[x, y], srcBytes[x - 1, y - 1], srcBytes[x, y - 1], srcBytes[x + 1, y - 1], srcBytes[x + 1, y], srcBytes[x + 1, y + 1], srcBytes[x, y + 1], srcBytes[x - 1, y + 1], srcBytes[x - 1, y] };
                        if (srcBytes[x, y] != 1)
                        {
                            if (CountN(srcTemp) >= 2 && CountN(srcTemp) <= 6)
                            {
                                if (CountT(srcTemp) == 1)
                                {
                                    if (srcBytes[x, y - 1] * srcBytes[x + 1, y] * srcBytes[x, y + 1] == 0)
                                    {
                                        if (srcBytes[x - 1, y] * srcBytes[x + 1, y] * srcBytes[x, y + 1] == 0)
                                        {
                                            srcBytes[x, y] = (byte)1;
                                            countNumber++;
                                        }
                                    }
                                    else
                                    {
                                        if (srcBytes[x, y - 1] * srcBytes[x + 1, y] * srcBytes[x - 1, y] == 0)
                                        {
                                            if (srcBytes[x, y - 1] * srcBytes[x, y + 1] * srcBytes[x - 1, y] == 0)
                                            {
                                                srcBytes[x, y] = (byte)1;
                                                countNumber++;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } while (countNumber != 0);
        }
        private static int CountN(params int[] src)
        {
            int count = 0;
            for (int i = 0; i < src.Length; i++)
            {
                if (src[i] == 0)
                {
                    count++;
                }
            }
            return count;
        }
        private static int CountT(params int[] src)
        {
            int count = 0;
            for (int i = 1; i < src.Length; i++)
            {
                if (src[i] == 1 && src[i - 1] == 0)
                {
                    count++;
                }
            }
            if (src[src.Length - 1] == 0 && src[0] == 1)
            {
                count++;
            }
            return count;
        }
相關文章
相關標籤/搜索