高斯模糊是通过 高斯核(Gaussian Kernel) 对图像进行卷积操作实现的. 二维高斯函数定义为
G ( x , y , σ ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x, y, \sigma) = \frac{1}{2\pi \sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} G(x,y,σ)=2πσ21e−2σ2x2+y2
其中:
以下是使用 OpenCV 计算不同尺度高斯模糊的代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('00001.jpg', cv2.IMREAD_COLOR_RGB)
# 定义高斯核的尺度(σ值)
sigma_values = [1.0, 1.6, 2.0, 2.5, 3.0] # 示例σ值
# 对每个σ值进行高斯模糊
blurred_images = []
for sigma in sigma_values:
# 高斯核大小(通常根据σ自动计算,如 ksize=(0,0))
blurred = cv2.GaussianBlur(img, (0, 0), sigmaX=sigma, sigmaY=sigma)
blurred_images.append(blurred)
# 显示结果
plt.figure(figsize=(15, 8))
# 原图
plt.subplot(2, 3, 1)
plt.imshow(img)
plt.title('original')
plt.axis('off')
# 模糊处理过的图
for i, (sigma, blurred) in enumerate(zip(sigma_values, blurred_images)):
plt.subplot(2, 3, i+2)
plt.imshow(blurred, cmap='gray')
plt.title(f'σ={sigma}')
plt.axis('off')
plt.tight_layout()
plt.show()
cv2.GaussianBlur(img, ksize, sigmaX)
ksize=(0,0)
时, OpenCV 会根据 σ \sigma σ 自动计算核大小, 通常为 6 σ + 1 6\sigma + 1 6σ+1sigmaX
和 sigmaY
是高斯核在 X 和 Y 方向的标准差, 通常设为相同值在实际计算中, 高斯核需要离散化为一个二维矩阵. 例如, 当 σ = 1.0 \sigma = 1.0 σ=1.0 时, 一个 3×3 的高斯核可能如下
K = 1 16 [ 1 2 1 2 4 2 1 2 1 ] K = \frac{1}{16} \begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \\ \end{bmatrix} K=161 121242121
手动计算高斯核的示例
import cv2
import numpy as np
# 生成二维高斯核
def gaussian_kernel(size, sigma):
kernel = np.zeros((size, size))
# // 是整数除法运算符, 会将结果向下取整到最接近的整数
center = size // 2
for x in range(size):
for y in range(size):
dx, dy = x - center, y - center
kernel[x, y] = np.exp(-(dx**2 + dy**2) / (2 * sigma**2))
kernel /= kernel.sum() # 归一化
return kernel
# 生成 σ=1.5 的 5x5 高斯核
kernel = gaussian_kernel(5, 1.5)
print(kernel)
矩阵中各元素的数值构成了一个三维高斯曲面, 中心点最高, 呈钟形向四周降低
SIFT(Scale-Invariant Feature Transform)算法是一种用于图像处理中的局部特征提取方法, 具有尺度、旋转和光照不变性, 因为其结果稳定性和较高的精度在图像匹配中广泛应用. SIFT的缺点是计算复杂度较高, 在一些需要实时处理的场景被快速算法如SURF, ORB等替代. 在 COLMAP 中, 提取特征量和匹配基于的就是 SIFT 算法.
目的: 在多尺度空间中寻找关键点(潜在的特征点)
目的: 精确定位关键点, 去除低对比度或边缘响应点
目的: 将关键点方向归一化处理, 以实现旋转不变性
目的: 在方向归一化处理后, 通过划分子块生成关键点的特征向量
import cv2
import matplotlib.pyplot as plt
# 读取图像(转为灰度图)
img = cv2.imread('00001.jpg', cv2.IMREAD_GRAYSCALE)
# 初始化 SIFT 检测器
sift = cv2.SIFT_create()
# 检测关键点并计算描述符
keypoints, descriptors = sift.detectAndCompute(img, None)
# 绘制关键点
img_with_keypoints = cv2.drawKeypoints(
img,
keypoints,
None,
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
)
# 显示结果
plt.figure(figsize=(10, 6))
plt.imshow(img_with_keypoints, cmap='gray')
plt.title('SIFT Keypoints')
plt.axis('off')
plt.show()
import cv2
import matplotlib.pyplot as plt
# 读取两张图像
img1 = cv2.imread('00001.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('00006.jpg', cv2.IMREAD_GRAYSCALE)
# 初始化 SIFT
sift = cv2.SIFT_create()
# 计算关键点和描述符
kp1, desc1 = sift.detectAndCompute(img1, None)
kp2, desc2 = sift.detectAndCompute(img2, None)
# 使用 BFMatcher(Brute-Force 匹配器)
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
matches = bf.match(desc1, desc2)
# 按距离排序,取最优匹配
matches = sorted(matches, key=lambda x: x.distance)
# 绘制前 50 个匹配点
matched_img = cv2.drawMatches(
img1, kp1,
img2, kp2,
matches[:10],
None,
flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS
)
# 显示匹配结果
plt.figure(figsize=(15, 8))
plt.imshow(matched_img, cmap='gray')
plt.title('SIFT Feature Matching')
plt.axis('off')
plt.show()