图像基本变换---Harris角点检测算法

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

算法过程如下:

1 使用梯度模板卷积求取梯度矩阵

对于灰度图像上的每一点,我们计算其在x,y方向上的一阶导数以及两者乘积,得到梯度图像矩阵Ix,Iy,Ixy。所使用模板如下:

Fig.1梯度模板

2 对于梯度矩阵Ix,Iy,Ixy分别进行高斯滤波,这里使用3*3的高斯模板进行滤波,模板如下:

图像基本变换---Harris角点检测算法_第1张图片

Fig.2高斯模板

3 计算图像中每个象素对应的角点响应函数值,得到响应矩阵,公式如下:

        4 设置CRF 的门限, 对提取的角点个数进行限制。局部极值点的数目往往很多, 通过设置CRF 的门限, 根据实际需要提取一定数量的最优点作为最后的结果。在矩阵cim中, 同时满足“cim 大于阈值thresh 和cim 是某邻域内的局部极大值” 这两个条件的点被认为是角点。提高阈值, 则提取的角点数目变少; 降低阈值, 则提取的角点数目变多。

  1. <span style=< span="" style="word-wrap: normal;">"font-size:14px;">[函数代码]  
  2.         ///   
  3.         /// Harris counter-detect.  
  4.         ///   
  5.         /// The source image.  
  6.         /// The threshould to control counters number.  
  7.         ///   
  8.         public static int[,] HarrisDetect(WriteableBitmap src, int CRF)  
  9.         {  
  10.             int x = src.PixelWidth;  
  11.             int y = src.PixelHeight;  
  12.             double[,] Ix = new double[x, y];  
  13.             double[,] Iy = new double[x, y];  
  14.             double[,] Ixy = new double[x, y];  
  15.             double[,] cim = new double[x, y];  
  16.             int[,] re = new int[x, y];  
  17.             double[,] srcBytes = GetImageBytes(src);  
  18.             GetIV(srcBytes, Ix, Iy, Ixy,x,y);  
  19.             GaussFilter(Ix, Iy, Ixy,x,y);  
  20.             cim = GetCim(Ix, Iy, Ixy,x,y);  
  21.             for (int j = 1; j < y - 1; j++)  
  22.             {  
  23.                 for (int i = 1; i < x - 1; i++)  
  24.                 {  
  25.                     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))  
  26.                     {  
  27.                         re[i, j] = 1;  
  28.                     }  
  29.                 }  
  30.             }  
  31.             return re;  
  32.         }  
  33.         //获得角点图像的 原始 信息  
  34.         public static double[,] GetImageBytes(WriteableBitmap src)  
  35.         {             
  36.             if (src != null)  
  37.             {  
  38.                 int w = src.PixelWidth;  
  39.                 int h = src.PixelHeight;  
  40.                 double[,] imageBytes = new double[w, h];  
  41.                 int b = 0, g = 0, r = 0;  
  42.                 byte[] temp = src.PixelBuffer.ToArray();  
  43.                 for (int y = 0; y < h; y++)  
  44.                 {  
  45.                     for (int x = 0; x < w * 4; x += 4)  
  46.                     {  
  47.                         b = temp[x + y * w * 4];  
  48.                         g = temp[x + 1 + y * w * 4];  
  49.                         r = temp[x + 2 + y * w * 4];  
  50.                         imageBytes[x, y] = (b * 0.114 + g * 0.587 + r * 0.299);  
  51.                     }  
  52.                 }  
  53.                 return imageBytes;  
  54.             }  
  55.             else  
  56.             {  
  57.                 return null;  
  58.             }  
  59.         }  
  60.         //梯度求取函数  
  61.         private static void GetIV(double[,] src, double[,] Ix, double[,] Iy, double[,] Ixy,int x,int y)  
  62.         {  
  63.             for (int j = 1; j < y - 1; j++)  
  64.             {  
  65.                 for (int i = 1; i < x - 1; i++)  
  66.                 {  
  67.                     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]);  
  68.                     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]);  
  69.                     Ixy[i, j] = Math.Abs(Ix[i, j] * Iy[i, j]);  
  70.                 }  
  71.             }  
  72.         }  
  73.         //高斯滤波函数(对梯度图像进行高斯滤波,这里采用的是3*3的高斯滤波模板)  
  74.         private static void GaussFilter(double[,] Ix, double[,] Iy, double[,] Ixy,int x,int y)  
  75.         {  
  76.             for (int j = 1; j < y - 1; j++)  
  77.             {  
  78.                 for (int i = 1; i < x - 1; i++)  
  79.                 {  
  80.                     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;  
  81.                     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;  
  82.                     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;  
  83.                 }  
  84.             }  
  85.         }  
  86.         //图像角点求取函数  
  87.         private static double[,] GetCim(double[,] Ix, double[,] Iy, double[,] Ixy,int x,int y)  
  88.         {  
  89.             double cim = 0;  
  90.             double[,] results = new double[x, y];  
  91.             for (int j = 1; j < y - 1; j++)  
  92.             {  
  93.                 for (int i = 1; i < x - 1; i++)  
  94.                 {  
  95.                     if (Ix[i, j] != 0 || Iy[i, j] != 0)  
  96.                     {  
  97.                         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]);  
  98.                         results[i, j] = cim;  
  99.                     }  
  100.                 }  
  101.             }  
  102.             return results;  
  103.         }  
  104.         //最大值获取函数  
  105.         private static double GetMax(params double[] src)  
  106.         {  
  107.             double tMax = 0;  
  108.             for (int i = 0; i < src.Length; i++)  
  109.             {  
  110.                 if (tMax < src[i])  
  111.                 {  
  112.                     tMax = src[i];  
  113.                 }  
  114.             }  
  115.             return tMax;  
  116.         }  
  117. <span style="font-size:14px;">[图像效果]  

图像基本变换---Harris角点检测算法_第2张图片

        

demo: http://www.zealfilter.com/forum.php?mod=viewthread&tid=27&extra=page%3D2

你可能感兴趣的:(图像基本变换)