图像特征可以包括颜色特征、纹理特征、形状特征以及局部特征点等。其中局部特点具有很好的稳定性,不容易受外界环境的干扰。图像特征提取是图像分析与图像识别的前提,它是将高维的图像数据进行简化表达最有效的方式,从一幅图像的的数据矩阵中,我们看不出任何信息,所以我们必须根据这些数据提取出图像中的关键信息,一些基本元件以及它们的关系。

图像局部特征描述的核心问题是不变性(鲁棒性)和可区分性。由于使用局部图像特征描述子的时候,通常是为了鲁棒地处理各种图像变换的情况。因此,在构建/设计特征描述子的时候,不变性问题就是首先需要考虑的问题。在宽基线匹配中,需要考虑特征描述子对于视角变化的不变性、对尺度变化的不变性、对旋转变化的不变性等;在形状识别和物体检索中,需要考虑特征描述子对形状的不变性。

局部特征点是图像特征的局部表达,它只能反应图像上具有的局部特殊性,所以它只适合于对图像进行匹配,检索等应用。对于图像理解则不太适合。而后者更关心一些全局特征,如颜色分布,纹理特征,主要物体的形状等。全局特征容易受到环境的干扰,光照,旋转,噪声等不利因素都会影响全局特征。相比而言,局部特征点,往往对应着图像中的一些线条交叉,明暗变化的结构中,受到的干扰也少。

对于局部特征的检测,通常使用局部图像描述子来进行。

斑点角点是两类局部特征点。斑点通常是指与周围有着颜色和灰度差别的区域,如草原上的一棵树或一栋房子。它是一个区域,所以它比角点的抗噪能力要强,稳定性要好。而角点则是图像中物体的拐角或者线条之间的交叉部分。

斑点检测原理与举例

LoG与DoH

斑点检测的方法主要包括利用高斯拉普拉斯算子检测的方法(LOG),以及利用像素点Hessian矩阵(二阶微分)及其行列式值的方法(DOH)。

DoH方法就是利用图像点二阶微分Hessian矩阵, Hessian矩阵行列式的值,同样也反映了图像局部的结构信息。与LoG相比,DoH对图像中的细长结构的斑点有较好的抑制作用。

无论是LoG还是DoH,它们对图像中的斑点进行检测,其步骤都可以分为以下两步:

  1. 使用不同的生成或模板,并对图像进行卷积运算;
  2. 在图像的位置空间与尺度空间中搜索LoG与DoH响应的峰值。

SIFT(尺度不变特征变换)

尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。该描述子具有非常强的稳健性。

SIFT算法详细介绍

SIFT算法步骤

  1. 构建DOG尺度空间

  2. 关键点搜索和定位:

  3. 方向赋值

  4. 关键点描述子生成

SIFT特征提取的优点

  1. SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;
  2. 独特性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;
  3. 多量性,即使少数的几个物体也可以产生大量的SIFT特征向量;
  4. 高速性,经优化的SIFT匹配算法甚至可以达到实时的要求;
  5. 可扩展性,可以很方便的与其他形式的特征向量进行联合;
  6. 需要较少的经验主义知识,易于开发。

SIFT特征提取的缺点

  1. 实时性不高,因为要不断地进行下采样和插值等操作;
  2. 有时特征点较少(比如模糊图像);
  3. 对边缘光滑的目标无法准确提取特征(比如边缘平滑的图像,检测出的特征点过少,对圆更是无能为力)。

SIFT特征提取可以解决的问题

目标的自身状态、场景所处的环境和成像器材的成像特性等因素影响图像配准/目标识别跟踪的性能。而SIFT算法在一定程度上可解决:

  1. 目标的旋转、缩放、平移(RST)
  2. 图像仿射/投影变换(视点viewpoint)
  3. 光照影响(illumination)
  4. 目标遮挡(occlusion)
  5. 杂物场景(clutter)
  6. 噪声

角点检测的原理与举例

角点检测的方法也是极多的,其中具有代表性的算法是Harris算法与FAST算法。
算法原理详解:Harris特征点检测FAST特征检测

Harris角点特征提取

Harris角点检测是一种基于图像灰度的一阶导数矩阵检测方法。检测器的主要思想是局部自相似性/自相关性,即在某个局部窗口内图像块与在各个方向微小移动后的窗口内图像块的相似性。该算法认为像素周围显示存在多余一个方向的边,便认为该点为兴趣点,即称为角点。

Harris算法步骤

  1. 利用水平、竖直差分算子对图像每个像素进行滤波以求得\(I_x, I_y\),进而求得图像域中点\(x\)上的对称半正定矩阵\(M_I = M_I(x)\)
    \[M_I=\nabla I \nabla I^T=\left[\begin{array}{c}I_x \\I_y\end{array}\right]\left[ \begin{array}{c}I_x & I_y\end{array}\right] = \left[ \begin{array}{cc} I_x^2 & I_x I_y \\ I_x I_y & I_y^2 \end{array}\right]\]
  2. 选择权重矩阵\(W\)(通常为高斯滤波器\(G\))对\(M\)进行滤波
    \[W = exp(- \frac{x^2+y^2}{2\sigma^2})\]
    \[ M_I = W * M_I\]
  3. 利用\(M\)计算对应于每个像素的角点量\(cim\)\(R\):
    \[cim = \frac{I_x^2*I_y^2-(I_xI_y)^2}{I_x^2+I_y^2}\]
  4. 在矩阵 \(cim\) 中,同时满足 \(cim\) 大于一阙值 \(thresh\)\(cim\) 是某领域内的局部极大值,这两个条件的点被认为是角点。

Harris角点性质

  1. 该算法算子对亮度和对比度的变化不敏感。

  2. 算子具有旋转不变性。

  3. 算子不具有尺度不变性。

Harris算法实现

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from scipy.ndimage import filters


class Harris:
    def __init__(self, img_path):
        self.img_path = img_path
        self.grayImg = None
        self.Ix = None
        self.Iy = None
        self.Ix_mul_Ix = None
        self.Ix_mul_Iy = None
        self.Iy_mul_Iy = None
        self.cim = None
        self.filtered_coords = None

    def _rgb2gray(self):
        self.grayImg = Image.open(self.img_path).convert('L')
        self.grayImg = np.array(self.grayImg)

    def _cal_ix_iy(self, sigma=3):
        # 计算导数
        self.Ix = np.zeros(self.grayImg.shape)
        filters.gaussian_filter(self.grayImg, (sigma, sigma), (0, 1), self.Ix)
        self.Iy = np.zeros(self.grayImg.shape)
        filters.gaussian_filter(self.grayImg, (sigma, sigma), (1, 0), self.Iy)

    def _cal_para(self):
        # 计算Ix^2,Iy^2和Ix*Iy并加入高斯滤波
        self.Ix_mul_Ix = filters.gaussian_filter(self.Ix*self.Ix, 3)
        self.Iy_mul_Iy = filters.gaussian_filter(self.Iy*self.Iy, 3)
        self.Ix_mul_Iy = filters.gaussian_filter(self.Ix*self.Iy, 3)

    def _cal_cim(self):
        self.cim = (self.Ix_mul_Ix*self.Iy_mul_Iy - 2*self.Ix_mul_Iy) / (self.Ix_mul_Ix + self.Iy_mul_Iy)

    def cal_harris(self, min_dist=10, threshold=0.1):
        self._rgb2gray()
        self._cal_ix_iy()
        self._cal_para()
        self._cal_cim()
        conner_threshold = self.cim.max()*threshold
        self.cim = (self.cim > conner_threshold) * 1
        coords = np.array(self.cim.nonzero()).T
        candidate_values = [self.cim[c[0], c[1]] for c in coords]
        index = np.argsort(candidate_values)
        allowed_locations = np.zeros(self.cim.shape)
        allowed_locations[min_dist:-min_dist, min_dist:-min_dist] = 1
        self.filtered_coords = []
        for i in index:
            if allowed_locations[coords[i, 0], coords[i, 1]] == 1:
                self.filtered_coords.append(coords[i])
                allowed_locations[(coords[i, 0] - min_dist):(coords[i, 0] + min_dist),
                (coords[i, 1] - min_dist):(coords[i, 1] + min_dist)] = 0  # 此处保证min_dist*min_dist只有一个harris特征点
        return self.filtered_coords

    def plot_harris_point(self):
        plt.figure()
        plt.gray()
        plt.imshow(Image.open(self.img_path).convert('L'))
        plt.plot([p[1] for p in self.filtered_coords], [p[0] for p in self.filtered_coords], '*')
        plt.axis('off')
        plt.show()


if __name__ == '__main__':
    img_path = "./imgs/3.jpg"
    harris = Harris(img_path)
    harris.cal_harris()
    harris.plot_harris_point()

结果演示

参考文献

python计算机视觉编程第2章
图像处理之特征提取
python计算机视觉编程之局部图像描述子
图像局部特征点检测算法综述
斑点检测
SIFT定位算法关键步骤的说明
SIFT算法详解
sift特征提取算法
Harris特征点检测
FAST特征检测
特征点提取之Harris角点提取法
Harris角点检测(一)

02-11 11:06