赞
踩
基于Harris角点实现两幅(不同角度拍摄)的图像匹配,基于RANSAC算法进行鲁棒性估计。算法的流程如下:
import numpy as np
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.util import img_as_float
from skimage.exposure import rescale_intensity
from skimage.transform import AffineTransform, warp
from skimage.feature import corner_harris, corner_peaks, corner_subpix,plot_matches
from skimage.measure import ransac
from matplotlib import pylab
temple = rgb2gray(img_as_float(imread(r'../../images/building.jpg'))) # 这样写可以读取两级相对路径
img_orig = np.zeros(list(temple.shape) + [3])
img_orig[..., 0] = temple
grad_row, grand_col = (np.mgrid[0:img_orig.shape[0],
0:img_orig.shape[1]] / float(img_orig.shape[0]))
img_orig[..., 1] = grad_row
img_orig[..., 2] = grand_col
img_orig = rescale_intensity(img_orig)
img_orig_gray = rgb2gray(img_orig)
affine_trans = AffineTransform(scale=(0.8, 0.9), rotation=0.1, translation=(120, -20))
image_warped = warp(img_orig, affine_trans.inverse, output_shape=img_orig.shape)
image_warped_gray = rgb2gray(image_warped)
# 计算图像中的感兴趣点--------------Harris角点 # harris corners coordinates_original = corner_harris(img_orig_gray) # threshold for an optimal value, depends on the image coordinates_original[coordinates_original > 0.01 * coordinates_original.max()] = 1 corner_coordinates_original = corner_peaks(coordinates_original, threshold_rel=0.0001, min_distance=5) # harris corners coordinates_warped = corner_harris(image_warped_gray) # threshold for an optimal value, depends on the image coordinates_warped[coordinates_warped > 0.01 * coordinates_warped.max()] = 1 corner_coordinates_warped = corner_peaks(coordinates_warped, threshold_rel=0.0001, min_distance=5) # 确定子像素角点的位置 coordinates_subpix_original = corner_subpix(img_orig_gray, corner_coordinates_original, window_size=9) coordinates_subpix_warped = corner_subpix(image_warped_gray, corner_coordinates_warped, window_size=9)
# 高斯权重:
def gaussian_weight(window_ext, sigma=1):
y, x = np.mgrid[-window_ext:window_ext + 1, -window_ext:window_ext + 1]
g_w = np.zeros(y.shape, dtype=np.double)
g_w[:] = np.exp(-0.5 * (x ** 2 / sigma ** 2 + y ** 2 / sigma ** 2))
g_w /= 2 * np.pi * sigma * sigma
return g_w
权重像素取决于到中心像素的距离,计算变形后图像中所有角点的误差平方加权和,用最小误差平方加权和的角点作为对应点
def match_corner(coord, window_ext=3): row, col = np.round(coord).astype(np.intp) window_original = img_orig[row - window_ext:row + window_ext + 1, col - window_ext:col + window_ext + 1, :] # 基于中心像素距离的权重计算 weights = gaussian_weight(window_ext, 3) weights = np.dstack((weights, weights, weights)) # 计算所有角点的误差平方加权和 SSDs = [] for coord_row, coord_col in corner_coordinates_warped: window_warped = image_warped[coord_row - window_ext:coord_row + window_ext + 1, coord_col - window_ext:coord_col + window_ext + 1, :] if window_original.shape == window_warped.shape: SSD = np.sum(weights * (window_original - window_warped) ** 2) # 加权求和 SSDs.append(SSD) min_idx = np.argmin(SSDs) if len(SSDs) > 0 else -1 return coordinates_subpix_warped[min_idx] if min_idx >= 0 else [None]
RANSAC算法进行鲁棒性估计。先将点分为内点和外点,然后在忽略外点的情况下将模型拟合到内点上,寻找与仿射变换一致的匹配。
src = [] dst = [] for coord in coordinates_subpix_original: coord1 = match_corner(coord) # 匹配点 if any(coord1) and len(coord1) > 0 and not all(np.isnan(coord1)): src.append(coord) dst.append(coord1) src = np.array(src) dst = np.array(dst) # 使用全部坐标估计仿射变换模型 model = AffineTransform() model.estimate(src, dst) # 鲁棒性估计基于RANSAC model_robust, inliers = ransac((src, dst), AffineTransform, min_samples=3, residual_threshold=2, max_trials=100) outliers = inliers == False # 比较真实和估计的变换参数 print(affine_trans.scale, affine_trans.translation, affine_trans.rotation) print(model.scale, model.translation, model.rotation) print(model_robust.scale, model_robust.translation, model_robust.rotation)
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(20, 15)) plt.gray() inlier_idxs = np.nonzero(inliers)[0] plot_matches(ax[0], img_orig_gray, image_warped_gray, src, dst, np.column_stack((inlier_idxs, inlier_idxs)), matches_color='b') ax[0].axis('off') ax[0].set_title('Correct correspondences', size=20) outlier_idxs = np.nonzero(outliers)[0] plot_matches(ax[1], img_orig_gray, image_warped_gray, src, dst, np.column_stack((outlier_idxs, outlier_idxs)), matches_color='r') ax[1].axis('off') ax[1].set_title('Faulty correspondences', size=20) fig.tight_layout() plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。