Win8 Metro(C#)数字图像处理--2.36角点检测算法



[函数名称]

Harris角点检测函数    HarrisDetect(WriteableBitmap src, int CRF)

[算法说明]

  目前的角点检测算法可归纳为3类:基于灰度图像的角点检测、基于二值图像的角点检测、基于轮廓曲线的角点检测。基于灰度图像的角点检测又可分为基于梯度、基于模板和基于模板梯度组合3类方法,其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。本文将介绍一种改进的Harris角点检测算法,该算法是一种基于模板与梯度组合的方法。

Win8 Metro(C#)数字图像处理--2.36角点检测算法_第1张图片

<strong><span style="font-size:14px;">[函数代码]</span></strong>
        /// <summary>
        /// Harris counter-detect.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <param name="v">The threshould to control counters number.</param>
        /// <returns></returns>
        public static int[,] HarrisDetect(WriteableBitmap src, int CRF)
        {
            int x = src.PixelWidth;
            int y = src.PixelHeight;
            double[,] Ix = new double[x, y];
            double[,] Iy = new double[x, y];
            double[,] Ixy = new double[x, y];
            double[,] cim = new double[x, y];
            int[,] re = new int[x, y];
            double[,] srcBytes = GetImageBytes(src);
            GetIV(srcBytes, Ix, Iy, Ixy,x,y);
            GaussFilter(Ix, Iy, Ixy,x,y);
            cim = GetCim(Ix, Iy, Ixy,x,y);
            for (int j = 1; j < y - 1; j++)
            {
                for (int i = 1; i < x - 1; i++)
                {
                    if ((cim[i, j] == GetMax(cim[i - 1, j - 1], cim[i, j - 1], cim[i + 1, j - 1], cim[i - 1, j], cim[i, j], cim[i + 1, j], cim[i - 1, j + 1], cim[i, j + 1], cim[i + 1, j + 1])) && (cim[i, j] > CRF))
                    {
                        re[i, j] = 1;
                    }
                }
            }
            return re;
        }
        //获得角点图像的 原始 信息
        public static double[,] GetImageBytes(WriteableBitmap src)
        {           
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[,] imageBytes = new double[w, h];
                int b = 0, g = 0, r = 0;
                byte[] temp = src.PixelBuffer.ToArray();
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w * 4; x += 4)
                    {
                        b = temp[x + y * w * 4];
                        g = temp[x + 1 + y * w * 4];
                        r = temp[x + 2 + y * w * 4];
                        imageBytes[x, y] = (b * 0.114 + g * 0.587 + r * 0.299);
                    }
                }
                return imageBytes;
            }
            else
            {
                return null;
            }
        }
        //梯度求取函数
        private static void GetIV(double[,] src, double[,] Ix, double[,] Iy, double[,] Ixy,int x,int y)
        {
            for (int j = 1; j < y - 1; j++)
            {
                for (int i = 1; i < x - 1; i++)
                {
                    Ix[i, j] = Math.Abs(src[i + 1, j - 1] + src[i + 1, j] + src[i + 1, j + 1] - src[i - 1, j - 1] - src[i - 1, j] - src[i - 1, j + 1]);
                    Iy[i, j] = Math.Abs(src[i - 1, j + 1] + src[i, j + 1] + src[i + 1, j + 1] - src[i - 1, j - 1] - src[i, j - 1] - src[i + 1, j - 1]);
                    Ixy[i, j] = Math.Abs(Ix[i, j] * Iy[i, j]);
                }
            }
        }
        //高斯滤波函数(对梯度图像进行高斯滤波,这里采用的是3*3的高斯滤波模板)
        private static void GaussFilter(double[,] Ix, double[,] Iy, double[,] Ixy,int x,int y)
        {
            for (int j = 1; j < y - 1; j++)
            {
                for (int i = 1; i < x - 1; i++)
                {
                    Ix[i, j] = (Ix[i - 1, j - 1] + Ix[i, j - 1] * 2 + Ix[i + 1, j - 1] + 2 * Ix[i - 1, j] + 4 * Ix[i, j] + 2 * Ix[i + 1, j] + Ix[i - 1, j + 1] + 2 * Ix[i, j + 1] + Ix[i + 1, j + 1]) / 16;
                    Iy[i, j] = (Iy[i - 1, j - 1] + Iy[i, j - 1] * 2 + Iy[i + 1, j - 1] + 2 * Iy[i - 1, j] + 4 * Iy[i, j] + 2 * Iy[i + 1, j] + Iy[i - 1, j + 1] + 2 * Iy[i, j + 1] + Ix[i + 1, j + 1]) / 16;
                    Ixy[i, j] = (Ixy[i - 1, j - 1] + Ixy[i, j - 1] * 2 + Ixy[i + 1, j - 1] + 2 * Ixy[i - 1, j] + 4 * Ixy[i, j] + 2 * Ixy[i + 1, j] + Ixy[i - 1, j + 1] + 2 * Ixy[i, j + 1] + Ix[i + 1, j + 1]) / 16;
                }
            }
        }
        //图像角点求取函数
        private static double[,] GetCim(double[,] Ix, double[,] Iy, double[,] Ixy,int x,int y)
        {
            double cim = 0;
            double[,] results = new double[x, y];
            for (int j = 1; j < y - 1; j++)
            {
                for (int i = 1; i < x - 1; i++)
                {
                    if (Ix[i, j] != 0 || Iy[i, j] != 0)
                    {
                        cim = Math.Abs(Ix[i, j] * Iy[i, j] - Ixy[i, j] * Ixy[i, j]) / (Ix[i, j] * Ix[i, j] + Iy[i, j] * Iy[i, j]);
                        results[i, j] = cim;
                    }
                }
            }
            return results;
        }
        //最大值获取函数
        private static double GetMax(params double[] src)
        {
            double tMax = 0;
            for (int i = 0; i < src.Length; i++)
            {
                if (tMax < src[i])
                {
                    tMax = src[i];
                }
            }
            return tMax;
        }
<strong><span style="font-size:14px;">[图像效果]</span></strong>
Win8 Metro(C#)数字图像处理--2.36角点检测算法_第2张图片

你可能感兴趣的:(Win8 Metro(C#)数字图像处理--2.36角点检测算法)