简介
计算机视觉图像特征提取是指从图像中提取出具有代表性的特征,以便计算机能够更好地理解和处理图像。常用的特征提取方法包括边缘检测、角点检测、纹理分析、颜色直方图等。在深度学习领域,卷积神经网络(CNN)也被广泛应用于图像特征提取任务。通过CNN,可以自动学习出图像中具有代表性的特征,从而提高计算机视觉领域的各项任务的准确性。
边缘检测
边缘检测是计算机视觉中一种常见的图像处理方法,用于检测图像中的边缘。在图像中,边缘是物体或场景中明显的亮度变化或颜色变化的位置,通常可以用来表示图像中的物体轮廓或物体边界。下面是几种常用算子的讲解:
1.Sobel算子
Sobel算子是一种基于梯度的边缘检测算子,其原理是通过计算图像中每个像素点周围像素点的亮度变化大小来检测图像中的边缘。Sobel算子可以分别检测图像中水平和垂直方向的边缘,最终将两个方向上的边缘合并得到最终的边缘检测结果。
其中,Gx表示水平方向上的梯度模板,Gy表示垂直方向上的梯度模板。Sobel算子可以通过将图像与Gx、Gy模板进行卷积操作,得到图像中每个像素点的梯度值,然后根据梯度值的大小来确定像素点是否为边缘像素。
2.Prewitt算子
Prewitt算子与Sobel算子类似,也是一种基于梯度的边缘检测算子,其原理与Sobel算子相似,不同之处在于Prewitt算子的模板不同。
3.Roberts算子
Roberts算子是一种基于差分的边缘检测算子,其原理是通过对图像进行差分操作,得到图像中每个像素点的梯度值,然后根据梯度值的大小来确定像素点是否为边缘像素。
4.Canny算子
Canny算子是一种基于多阶段处理的边缘检测算子,其原理是通过对图像进行高斯滤波、计算梯度、非极大值抑制、双阈值处理等多个阶段的处理,最终得到图像中高质量的边缘检测结果。Canny算子在实际应用中具有较高的精度和稳定性,被广泛应用于计算机视觉领域的各种任务中。
角点检测
角点检测是计算机视觉中的一种重要算法,用于寻找图像中的角点,也称为兴趣点。角点是图像中具有局部最大曲率或变化率的位置,通常被认为是图像中最具有特征性的点之一。角点检测可以用于图像匹配、三维重建、目标跟踪等领域。
1.Harris角点检测算法
Harris角点检测算法基于图像的灰度值变化来判断是否为角点。该算法计算每个像素点周围邻域的自相关矩阵,并用矩阵的特征值来判断该点是否为角点。如果特征值都比较大,则该点为角点;如果只有一个特征值比较大,则该点为边缘点;如果两个特征值都比较小,则该点为平滑区域。
C++实现
Mat src = imread("test.jpg");
if (src.empty()) {
cout << "Could not open or find the image!\n" << endl;
return -1;
}
Mat src_gray, dst, dst_norm, dst_norm_scaled;
int blockSize = 2;
int apertureSize = 3;
double k = 0.04;
int thresh = 200;
cvtColor(src, src_gray, COLOR_BGR2GRAY);
dst = Mat::zeros(src.size(), CV_32FC1);
cornerHarris(src_gray, dst, blockSize, apertureSize, k);
normalize(dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
convertScaleAbs(dst_norm, dst_norm_scaled);
for (int i = 0; i < dst_norm.rows; i++) {
for (int j = 0; j < dst_norm.cols; j++) {
if ((int)dst_norm.at<float>(i, j) > thresh) {
circle(dst_norm_scaled, Point(j, i), 5, Scalar(0), 2, 8, 0);
}
}
}
Python
blockSize = 2
apertureSize = 3
k = 0.04
thresh = 200
dst = cv2.cornerHarris(gray, blockSize, apertureSize, k)
dst_norm = np.empty_like(dst)
cv2.normalize(dst, dst_norm, 0, 255, cv2.NORM_MINMAX)
dst_norm_scaled = cv2.convertScaleAbs(dst_norm)
for i in range(dst_norm.shape[0]):
for j in range(dst_norm.shape[1]):
if dst_norm[i,j] > thresh:
cv2.circle(dst_norm_scaled, (j,i), 5, (0), 2)
需要注意的是,在实际应用中,需要根据图像的具体特点来调整算法的参数,以获得更好的效果。同时,Harris角点检测算法也存在一些限制,比如对旋转和尺度变换不具有不变性,因此,在实际应用中需要结合其他算法,以提高检测的准确性和鲁棒性。
Shi-Tomasi角点检测算法
Shi-Tomasi角点检测算法是对Harris角点检测算法的改进,它计算每个像素点周围邻域的最小特征值,并用最小特征值来判断该点是否为角点。该算法比Harris算法更加稳健,能够更好地处理图像中的噪声和图像变换。
maxCorners = 100
qualityLevel = 0.01
minDistance = 10
corners = cv2.goodFeaturesToTrack(gray, maxCorners, qualityLevel, minDistance)
corners = np.int0(corners)
for i in corners:
x,y = i.ravel()
cv2.circle(img,(x,y),3,(0,0,255),-1)
使用OpenCV库实现了Shi-Tomasi
角点检测算法,对输入的图像进行角点检测,并将结果显示出来。其中,maxCorners表示最多检测的角点数,qualityLevel
是角点质量的阈值,minDistance
是角点之间的最小距离。
FAST角点检测算法
FAST(Features from Accelerated Segment Test)角点检测算法是一种用于实时图像处理的高效角点检测算法。该算法通过比较像素点与其邻域像素点的灰度值来判断该点是否为角点,从而实现快速检测角点的功能。
FAST角点检测算法的具体实现步骤如下:
- 选择一个像素点p作为候选角点;
- 设置一个阈值t,将p的灰度值与其邻域内所有像素的灰度值进行比较,如果p的灰度值与其中n个像素的灰度值之差都大于t,则认为该点为角点;
- 为了避免检测到邻域内的多个像素点作为角点,需要对检测到的角点进行非极大值抑制,即只保留灰度值最大的角点。
需要注意的是,在实际应用中,需要根据图像的具体特点来调整算法的参数,以获得更好的效果。同时,FAST角点检测算法也存在一些限制,比如对噪声和图像变换的鲁棒性较差,需要结合其他算法进行增强。
fast = cv2.FastFeatureDetector_create()
kp = fast.detect(gray, None)
img2 = cv2.drawKeypoints(img, kp, None, color=(0,255,0))
其中,cv2.FastFeatureDetector_create
用于创建FAST角点检测器,kp为检测到的关键点。
纹理分析
纹理分析在计算机视觉、图像处理、机器学习等领域有着广泛的应用,例如图像分类、图像检索、医学影像分析、人脸识别等。在实际应用中,需要根据具体的任务和图像特点,选择合适的纹理分析方法,并对算法进行优化和改进,以获得更好的效果。
1.灰度共生矩阵(GLCM)
灰度共生矩阵是一种用于描述图像中灰度分布的方法。它可以统计图像中相邻像素之间的灰度值差异,并生成一个共生矩阵。通过对这个共生矩阵进行分析和计算,可以提取出图像中的纹理特征。
- 将图像进行灰度化处理;
- 根据指定的距离和方向参数,计算图像中相邻像素之间的灰度值差异,并统计每种差异出现的次数,生成共生矩阵;
- 根据共生矩阵计算出各种纹理特征,例如对比度、能量、熵、相关性等。
2.局部二值模式(LBP)
局部二值模式是一种用于描述图像中纹理特征的方法。它可以通过比较像素点与其邻域像素点的灰度值,来判断该像素点所属的纹理类型。通过对图像中所有像素点进行局部二值模式计算,可以生成用于分类和检索的特征向量。
# 定义 LBP 算法函数
def LBP(img, radius=1, neighbors=8):
height, width = img.shape
lbp_img = np.zeros((height, width), dtype=np.uint8)
for row in range(radius, height - radius):
for col in range(radius, width - radius):
center = img[row, col]
code = 0
for i in range(neighbors):
x = col + int(radius * np.cos(2 * np.pi * i / neighbors))
y = row - int(radius * np.sin(2 * np.pi * i / neighbors))
if img[y, x] > center:
code += 1 << i
lbp_img[row, col] = code
return lbp_img
# 计算 LBP 图像
lbp_img = LBP(gray)
需要注意的是,在计算 LBP 图像时,需要对边缘像素进行特殊处理,以免出现越界问题。
方向梯度直方图
方向梯度直方图(Histogram of Oriented Gradients,HOG)是一种用于描述图像纹理特征的方法,它可以通过计算图像中局部区域的梯度方向和大小来得到该区域的方向梯度直方图,从而描述图像的纹理特征。HOG 算法具有良好的旋转不变性和局部不变性,常用于目标检测、人脸识别等领域。
# 计算 HOG 特征向量
hog_feature, hog_image = hog(gray, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(2, 2), block_norm='L2-Hys', visualize=True)
在计算 HOG 特征向量时,需要使用第三方库 skimage。总的来说,HOG 算法是一种基于梯度方向的图像纹理特征描述方法,可以用于图像分类、目标检测、人脸识别等领域。在实际应用中,需要根据具体的任务和图像特点,选择合适的算法,并对算法进行优化和改进,以获得更好的效果。
颜色直方图
颜色直方图(Color Histogram)是一种用于描述图像颜色分布的方法,它可以统计图像中每个像素的颜色分布情况,并将其表示为一个直方图。颜色直方图通常用于图像检索、图像分类、目标识别等领域。