不愧是北理CV博士,算法原理脱口而出。。。


Hello,我是kk~
两天前,和之前大学同学碰面,聊了聊。今年刚刚博士毕业。
大学那会儿就属于理论和实践,都是顶尖的那种大神。
聊到硕博士毕业,科研、paper,永远是最头疼的。现在很多人都在做cv方向的事情,聊到小样本学习、模型解释性和可解释性、对抗攻击与鲁棒性、自监督学习和弱监督学习、多模态学习等等等。
后来说到一些细节的事情。图像特征提取方法,在论文中有很大的优势,不愧是博士,脱口就来,特别细致。
咱们今天就好好聊聊关于图像特征提取方法的理论点。
实际上,在计算机视觉和图像处理领域的研究中,特征提取是一个非常重要的环节,因为它直接影响着后续任务的性能和效果。因此,在学术论文中,特征提取方法通常是至关重要的一部分,并且往往会被详细地介绍、探讨和评估。
说几点优势:
方法介绍与创新:论文可以详细介绍提出的特征提取方法,并阐明其原理、设计思路以及与现有方法的区别和优势。这有助于学术界了解新方法的创新之处。
实验验证和性能评估:论文通常会对提出的特征提取方法进行实验验证和性能评估,以验证其有效性、鲁棒性和泛化能力。这有助于展示方法的实用性和可行性。
问题解决与应用推广:特征提取方法往往是解决特定问题或任务的关键步骤之一。通过在论文中介绍特征提取方法,可以帮助解决特定领域或应用中的实际问题,并推广到其他相关领域。
图像特征提取方法在学术论文中是非常适合应用的,是学术研究的重要组成部分。
下面,总结了十大特征提取的方法,给出每种方法详细的原理以及一个能够说明问题的Python代码。
代码方面,给到了详细的注释,并且大家可以直接执行。
在后续所有的代码中,均采用lenna图像,如果大家需要该图片,后台回复“数据集”可获取~ 
一起来看~
HOG(Histogram of Oriented Gradients)
Histogram of Oriented Gradients(HOG)是一种用于目标检测和图像识别的特征描述子。它是一种用来描述图像局部梯度方向分布的方法。HOG特征主要用于人体检测等计算机视觉任务中。
原理
图像梯度计算:首先,对图像进行灰度化处理,然后计算每个像素点的梯度的大小和方向。这可以通过使用Sobel算子等方法来实现。
图像划分:将图像划分成小的单元(cells),每个单元内的像素梯度方向信息被累积在一个直方图中。
直方图归一化:对每个单元的直方图进行归一化,使得对光照变化更加鲁棒。
块合并:将相邻的单元组合成块(blocks),并将每个块内的归一化直方图串联起来形成最终的特征向量。
特征向量:最终,将所有块的特征向量串联起来,形成整个图像的特征向量。
公式表达
令 
 为输入图像, 
 和 
 分别为图像 
 在 
 和 
 方向上的梯度, 
 是梯度的方向,则每个像素的梯度大小 
 和方向 
 可以通过以下公式计算:
Python案例
import cv2import numpy as npangle_unit = None  # 在全局范围内定义 angle_unitdef hog_descriptor(image):    global angle_unit  # 在函数内部引用全局变量 angle_unit    # 计算图像的梯度    gx = cv2.Sobel(image, cv2.CV_32F, 1, 0)    gy = cv2.Sobel(image, cv2.CV_32F, 0, 1)    magnitude, angle = cv2.cartToPolar(gx, gy)    # 将角度转换到0~180度范围    angle = np.degrees(angle) % 180    # 绘制梯度方向直方图    cell_size = (8, 8)    bin_size = 9    angle_unit = 180 / bin_size  # 设置 angle_unit 的值    gradient_histogram = np.zeros((image.shape[0] // cell_size[0], image.shape[1] // cell_size[1], bin_size))    cell_gradient_vector = np.zeros((image.shape[0] // cell_size[0], image.shape[1] // cell_size[1], bin_size))    for i in range(cell_gradient_vector.shape[0]):        for j in range(cell_gradient_vector.shape[1]):            cell_magnitude = magnitude[i * cell_size[0]:(i + 1) * cell_size[0],                             j * cell_size[1]:(j + 1) * cell_size[1]]            cell_angle = angle[i * cell_size[0]:(i + 1) * cell_size[0],                         j * cell_size[1]:(j + 1) * cell_size[1]]            cell_gradient_vector[i][j] = cell_gradient(cell_magnitude, cell_angle, bin_size)    # 对梯度方向直方图进行汇总,归一化并转换为图像    hog_image = np.sum(cell_gradient_vector, axis=2)  # 对最后一个维度求和    hog_image = cv2.normalize(hog_image, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)  # 归一化到0到255范围内    return hog_imagedef cell_gradient(cell_magnitude, cell_angle, bin_size):    global angle_unit  # 在函数内部引用全局变量 angle_unit    orientation_centers = [0] * bin_size    for k in range(cell_magnitude.shape[0]):        for l in range(cell_magnitude.shape[1]):            gradient_strength = cell_magnitude[k][l]            gradient_angle = cell_angle[k][l]            min_angle, max_angle, mod = nearest_bin(gradient_angle, bin_size)            orientation_centers[min_angle] += (gradient_strength * (1 - (mod / angle_unit)))            orientation_centers[max_angle] += (gradient_strength * (mod / angle_unit))    return orientation_centersdef nearest_bin(gradient_angle, bin_size):    global angle_unit  # 在函数内部引用全局变量 angle_unit    idx = int(gradient_angle / angle_unit)    mod = gradient_angle % angle_unit    if idx >= bin_size - 1:        return idx - (bin_size - 1), 0, mod    else:        return idx, idx + 1, mod# 读取图像image = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)# 计算HOG特征hog = hog_descriptor(image)# 输出HOG特征图像cv2.imshow('HOG Descriptor', hog)cv2.waitKey(0)cv2.destroyAllWindows()
这是一个简单的使用OpenCV实现的HOG特征提取的示例。大家可以通过调用hog_descriptor()函数来计算图像的HOG特征,然后将其可视化以理解其含义。
SIFT(Scale-Invariant Feature Transform)
Scale-Invariant Feature Transform(SIFT)是一种用于检测和描述图像中的局部特征的算法,它具有尺度不变性和旋转不变性,因此在图像匹配和目标识别中广泛应用。
原理
尺度空间极值检测:通过在不同的尺度下对图像进行高斯模糊,然后使用高斯差分函数来检测图像中的关键点。
关键点定位:对于每个检测到的尺度空间极值点,使用DoG函数的Taylor展开来精确定位关键点,并通过去除低对比度的关键点和边缘响应来过滤无关的关键点。
关键点方向分配:为每个关键点分配一个主方向,以提高特征的旋转不变性。
关键点描述:在关键点的周围区域内创建一个方向梯度直方图,然后生成一个128维的特征向量来描述关键点的局部特征。
Python案例
import cv2# 读取图像image = cv2.imread('lenna.jpg')gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 初始化SIFT检测器sift = cv2.SIFT_create()# 检测关键点和计算描述符keypoints, descriptors = sift.detectAndCompute(gray_image, None)# 绘制关键点image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)# 显示图像cv2.imshow('SIFT Keypoints', image_with_keypoints)cv2.waitKey(0)cv2.destroyAllWindows()

这是一个简单的使用OpenCV实现的SIFT特征提取的示例。可以通过调用detectAndCompute()函数来检测图像的关键点并计算其描述符,然后将其可视化以理解其含义。
SURF(Speeded Up Robust Features)
Speeded Up Robust Features(SURF)是一种用于检测和描述图像中的局部特征的算法,它是SIFT的一种改进版本,具有更高的速度和更好的性能。
原理
快速特征检测:SURF使用一种称为盒子滤波器(Box Filter)的加速技术来快速检测图像中的特征点。
关键点定位:通过检测图像中的极值点来定位关键点,然后通过Hessian矩阵的行列式来确定特征点的主方向。
描述符生成:在每个关键点周围的区域内计算Haar小波特征,然后将这些特征组合成一个特征向量来描述关键点的局部特征。
公式表达
SURF算法中使用的盒子滤波器和Haar小波特征是数学上定义的,但由于较为复杂,这里不进行公式表达。
Python案例
import cv2# 读取图像image = cv2.imread('lenna.jpg')gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 初始化ORB检测器orb = cv2.ORB_create()# 检测关键点和计算描述符keypoints, descriptors = orb.detectAndCompute(gray_image, None)# 绘制关键点image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)# 显示图像cv2.imshow('ORB Keypoints', image_with_keypoints)cv2.waitKey(0)cv2.destroyAllWindows()

这是一个简单的使用OpenCV实现的SURF特征提取的示例。大家可以通过调用detectAndCompute()函数来检测图像的关键点并计算其描述符,然后将其可视化以理解其含义。
ORB(Oriented FAST and Rotated BRIEF)
Oriented FAST and Rotated BRIEF(ORB)是一种用于检测和描述图像中的局部特征的算法,它结合了FAST关键点检测器和BRIEF描述符,同时具有旋转不变性和尺度不变性。
原理
FAST关键点检测:使用FAST(Features from Accelerated Segment Test)算法快速检测图像中的关键点。FAST是一种高效的角点检测算法,用于快速定位图像中的感兴趣点。
Harris角点响应:对FAST检测到的关键点进行角点响应的计算,以进一步筛选稳定的关键点。
关键点方向分配:为每个关键点分配一个主方向,以提高特征的旋转不变性。
BRIEF描述符生成:在关键点周围的区域内计算BRIEF(Binary Robust Independent Elementary Features)描述符,该描述符利用图像中的像素对来生成二进制的特征描述子。
Python案例
import cv2# 读取图像image = cv2.imread('lenna.jpg')gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 初始化ORB检测器orb = cv2.ORB_create()# 检测关键点和计算描述符keypoints, descriptors = orb.detectAndCompute(gray_image, None)# 绘制关键点image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)# 显示图像cv2.imshow('ORB Keypoints', image_with_keypoints)cv2.waitKey(0)cv2.destroyAllWindows()
这是一个简单的使用OpenCV实现的ORB特征提取的示例。大家可以通过调用detectAndCompute()函数来检测图像的关键点并计算其描述符,然后将其可视化以理解其含义。
CNN特征提取(Convolutional Neural Networks)
卷积神经网络(Convolutional Neural Networks,CNN)是一种在计算机视觉领域广泛应用的深度学习模型。它能够有效地从图像中提取特征,并在诸如图像分类、目标检测、图像分割等任务中取得良好效果。
原理
CNN的核心思想是通过卷积层(Convolutional Layer)和池化层(Pooling Layer)来提取图像的特征。卷积层通过滤波器(Filter)与输入图像进行卷积操作,从而检测图像中的边缘、纹理等特征。池化层则通过降采样的方式减小特征图的尺寸,同时保留最显著的特征。经过多个卷积层和池化层的堆叠,最终得到的特征图会被展平并输入到全连接层(Fully Connected Layer)进行分类或其他任务。
公式表达
卷积操作:
其中,
 是输入图像,
 是卷积核,
 是输出的特征图。
池化操作: 池化操作通常使用最大池化或平均池化,其中最大池化的公式为:
其中,
 是池化后的特征图。
Python案例
以下是一个简单的Python案例,演示如何使用Keras库构建一个简单的CNN模型,并对输入的图像进行特征提取:
import numpy as npimport matplotlib.pyplot as pltfrom keras.models import Sequentialfrom keras.layers import Conv2D, MaxPooling2D# 创建一个简单的CNN模型model = Sequential()model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))model.add(MaxPooling2D((2, 2)))model.add(Conv2D(64, (3, 3), activation='relu'))model.add(MaxPooling2D((2, 2)))model.add(Conv2D(64, (3, 3), activation='relu'))# 加载一个示例图像并进行预处理image = np.random.random((28, 28, 1))image = np.expand_dims(image, axis=0)# 使用模型提取特征features = model.predict(image)# 输出特征图plt.imshow(features[0, :, :, 0], cmap='gray')plt.show()
这段代码首先创建了一个简单的CNN模型,包括两个卷积层和两个池化层。然后加载了一个随机生成的28x28的灰度图像,并使用模型提取了特征。最后将提取的特征图进行可视化展示。

运行以上代码会输出一个提取的特征图像,其中包含了经过模型学习到的图像特征。
这个案例可以帮助初学者理解CNN的基本原理和实现方法,但要深入理解CNN的原理还需要进一步学习。
Gabor滤波器
Gabor滤波器是一种在计算机视觉和图像处理领域广泛使用的特征提取工具。它被设计用于检测图像中的纹理和边缘等特征,同时对于不同方向和频率的纹理具有较好的适应性。下面我将详细解释Gabor滤波器的原理、公式表达、Python案例,并展示如何使用Python生成并输出Gabor滤波器的图像。
原理
Gabor滤波器的原理基于Gabor函数。Gabor函数是一种复数函数,它在空间域和频率域中都具有局部性和多尺度性质。在图像处理中,Gabor函数用于构建Gabor滤波器,用于提取图像中的纹理特征。Gabor滤波器可以在不同方向和频率上对图像进行滤波,因此能够检测出图像中不同尺度和方向上的纹理。
公式表达
Gabor函数的数学表达式如下:
其中,
 和 
 是坐标 
 在旋转角度 
 后的坐标;
 是波长;
 是滤波器的方向;
 是相位偏移;
 是高斯函数的标准差;
 是空间纵横比。
Python案例
下面是一个使用Python生成Gabor滤波器并输出图像的示例:
import numpy as npimport cv2import matplotlib.pyplot as pltdef gabor_filter(size, theta, sigma, lambd, gamma, psi):    kernel = cv2.getGaborKernel((size, size), sigma, theta, lambd, gamma, psi, ktype=cv2.CV_32F)    return kerneldef visualize_filter(kernel):    plt.figure(figsize=(5, 5))    plt.imshow(kernel, cmap='gray')    plt.title('Gabor Filter')    plt.axis('off')    plt.show()# 参数设置size = 31theta = np.pi / 4  # 滤波器的方向,这里取 45 度sigma = 2.0lambd = 10.0  # 波长gamma = 0.5psi = 0# 生成并可视化Gabor滤波器kernel = gabor_filter(size, theta, sigma, lambd, gamma, psi)visualize_filter(kernel)
这段代码首先定义了一个函数 gabor_filter 来生成Gabor滤波器,然后使用 visualize_filter 函数可视化生成的滤波器。在示例中,我们设定了滤波器的方向为 45 度,标准差为 2.0,波长为 10.0,空间纵横比为 0.5,相位偏移为 0。

运行以上代码,将生成并显示一个Gabor滤波器的图像,该图像将显示出滤波器在不同方向上的特征响应。
LBP(Local Binary Pattern)
LBP(Local Binary Pattern)是一种用于纹理分析的特征提取方法,在图像处理和计算机视觉领域被广泛应用。它对图像的局部纹理模式进行编码,能够有效地描述图像中的纹理信息。下面我将详细解释LBP的原理、公式表达、Python案例,并展示如何使用Python生成并输出LBP图像。

LBP算法通过比较像素点与其周围邻域像素的灰度值来生成二进制模式,然后将这些二进制模式组合成一个整数作为该像素点的特征值。具体步骤如下:
选择图像中的一个像素点以及其周围的邻域像素。
将邻域像素的灰度值与中心像素的灰度值进行比较,将比中心像素大的像素标记为1,否则标记为0。
将得到的二进制串转换为一个十进制数,作为该像素点的LBP特征值。
通过对图像中的每个像素点应用上述步骤,可以得到整个图像的LBP特征图。
公式表
LBP的数学表达式如下:
其中,
 是邻域像素点的数量,
 是邻域半径,
 是中心像素的坐标,
 是中心像素的灰度值,
是邻域像素的灰度值,
 是一个阶跃函数:
Python案
下面是一个使用Python生成LBP图像的示例:
import cv2import numpy as npimport matplotlib.pyplot as pltdef lbp(image, P, R):    height, width = image.shape    lbp_image = np.zeros_like(image)    for y in range(R, height - R):        for x in range(R, width - R):            center = image[y, x]            binary_pattern = 0            for p in range(P):                # 计算邻域像素的坐标                x_p = x + int(R * np.cos(2 * np.pi * p / P))                y_p = y - int(R * np.sin(2 * np.pi * p / P))                # 计算邻域像素的灰度值                neighbor = image[y_p, x_p]                # 更新二进制模式                if neighbor >= center:                    binary_pattern |= 1 << p            lbp_image[y, x] = binary_pattern    return lbp_image# 读取图像image = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)# 设置参数P = 8  # 邻域像素数量R = 1  # 邻域半径# 计算LBP图像lbp_image = lbp(image, P, R)# 可视化结果plt.figure(figsize=(8, 4))plt.subplot(1, 2, 1)plt.imshow(image, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(lbp_image, cmap='gray')plt.title('LBP Image')plt.axis('off')plt.show()
运行以上代码,将会显示原始图像和经过LBP算法处理后的LBP图像。通过对比两幅图像,可以直观地观察到LBP算法提取的纹理特征。

Edge Detection(边缘检测)
边缘检测是图像处理中常用的技术,用于检测图像中的边缘或轮廓。边缘通常表示图像中灰度变化较大的区域,它们是图像中重要的特征之一。下面我将详细解释边缘检测的原理、公式表达、Python案例,并展示如何使用Python生成并输出边缘检测结果图像。
原理
边缘检测的原理是基于图像中灰度的变化。在边缘处,像素的灰度值通常会发生明显的变化。边缘检测算法通过计算图像中相邻像素之间的灰度差异来寻找这些变化,从而确定边缘的位置。
公式表达
常见的边缘检测算法包括Sobel算子、Prewitt算子、Canny边缘检测等。这些算法通常使用卷积运算来计算图像中每个像素点的梯度值,进而确定边缘的位置。
以Sobel算子为例,其在水平和垂直方向上的卷积核分别为:
图像中每个像素点的梯度幅值可以通过下式计算得到:
Python案例
下面是一个使用Python进行边缘检测的示例:
import cv2import numpy as npimport matplotlib.pyplot as plt# 读取图像image = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)# 使用Sobel算子进行边缘检测sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)gradient_magnitude = np.sqrt(sobel_x ** 2 + sobel_y ** 2)# 可视化结果plt.figure(figsize=(10, 5))plt.subplot(1, 3, 1)plt.imshow(image, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(1, 3, 2)plt.imshow(sobel_x, cmap='gray')plt.title('Sobel X')plt.axis('off')plt.subplot(1, 3, 3)plt.imshow(sobel_y, cmap='gray')plt.title('Sobel Y')plt.axis('off')plt.show()
运行以上代码,将会显示原始图像以及经过Sobel算子进行水平和垂直边缘检测后的图像。观察这些图像可以帮助初学者理解边缘检测算法的原理和效果。

Color Histograms(颜色直方图)
颜色直方图是图像处理中常用的一种特征表示方法,用于描述图像中各种颜色的分布情况。它可以帮助我们了解图像中的颜色信息,进而用于图像分类、检索、分割等任务。下面我将详细解释颜色直方图的原理、公式表达、Python案例,并展示如何使用Python生成并输出颜色直方图图像。
原理
颜色直方图是一种统计图,它统计了图像中每个颜色通道(如红、绿、蓝)的像素数量或像素比例。通过分析颜色直方图,我们可以了解图像中不同颜色的分布情况,进而对图像进行分析和处理。
公式
假设图像具有三个颜色通道(红、绿、蓝),那么颜色直方图可以表示为一个三维数组,其中每个维度对应一个颜色通道。颜色直方图的计算方法通常是统计每个颜色通道中像素的数量或像素的占比。
Python案例
下面是一个使用Python计算和绘制颜色直方图的示例:
import cv2import matplotlib.pyplot as plt# 读取图像image = cv2.imread('lenna.jpg')# 将图像转换为RGB格式image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 计算颜色直方图histogram = cv2.calcHist([image], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])# 绘制颜色直方图plt.figure(figsize=(10, 5))plt.subplot(1, 2, 1)plt.imshow(image)plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.plot(histogram[:, :, 0], color='red')plt.plot(histogram[:, :, 1], color='green')plt.plot(histogram[:, :, 2], color='blue')plt.title('Color Histogram')plt.xlabel('Pixel Value')plt.ylabel('Frequency')plt.legend(['Red', 'Green', 'Blue'])plt.grid(True)plt.show()
运行以上代码,将会显示原始图像和计算得到的颜色直方图。在颜色直方图中,横轴表示像素值,纵轴表示像素的数量或占比。通过观察颜色直方图,可以直观地了解图像中不同颜色通道的分布情况。

PCA-SIFT
PCA-SIFT是SIFT(Scale-Invariant Feature Transform,尺度不变特征变换)算法的一种改进版本,它结合了主成分分析(PCA)和SIFT特征提取算法,用于提取图像中的关键点和描述子。下面我将详细解释PCA-SIFT的原理、公式表达、Python案例,并展示如何使用Python生成并输出PCA-SIFT特征点图像。
原理
PCA-SIFT的原理是将SIFT特征描述子进行降维,降低其维度,从而减少存储空间和计算复杂度。它通过主成分分析(PCA)对SIFT描述子进行降维,保留描述子中最重要的信息,从而实现对图像特征的高效表示。
公式表达
PCA-SIFT的核心公式是PCA降维的过程。给定一组SIFT特征描述子矩阵
,其中每一行代表一个SIFT描述子,每一列代表一个特征维度,假设原始SIFT描述子的维度为
,我们通过PCA将其降维到
维,其中
。PCA的过程可以用下面的公式表达:
其中,
是降维后的特征矩阵,
是原始特征矩阵,
是PCA的投影矩阵,用于将原始特征映射到低维空间。
Python案例
下面是一个使用Python实现PCA-SIFT的示例:
import cv2import numpy as np# 读取图像image = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)# 初始化SIFT对象sift = cv2.SIFT_create()# 检测关键点和计算描述子keypoints, descriptors = sift.detectAndCompute(image, None)# 使用PCA进行降维pca = cv2.PCACompute(descriptors, mean=None, maxComponents=128)[1]# 输出降维后的特征维度print("PCA-SIFT特征维度:", pca.shape)# 可视化关键点image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)cv2.imshow('Keypoints', image_with_keypoints)cv2.waitKey(0)cv2.destroyAllWindows()

运行以上代码,将会显示图像中检测到的关键点,并输出PCA-SIFT特征维度。通过观察可视化的关键点,可以直观地了解PCA-SIFT算法对图像中的特征点的提取效果。
最后
添加微信:kkcoder,备注:CV、NLP,拉你入群,一起学习。

好了,今天的内容先这样,继续想看解决什么问题,评论区留言~
最近我们花了几个月整理的一个内容,可meeting的idea !!
绝对绝对不可错过的一个内容~ 

都到这里了,记得点赞哦~
到顶部