本帖最后由 fantomas 于 2018-10-19 09:56 编辑
openCV【实践系列】1——OpenCV中的图像对齐
在典型的图像对齐问题中,我们有两个场景图像,它们通过运动模型相关联。不同的图像对齐算法旨在使用不同的技巧和假设来估计这些运动模型的参数。一旦知道这些参数,将一个图像变形以使其与另一个图像对齐是直截了当的。 让我们快速了解这些运动模型 这些模型在OpenCV中是常常具有前缀MOTION_: 1. 平移(MOTION_TRANSLATION):第一个图像可以被移位(x,y)来获得第二个图像,我们只需要估算两个参数x和y。 2. 欧氏(MOTION_EUCLIDEAN):第三张图像是第一个图像是第二个图像的旋转和移位版本。所以有三个参数x,y和角度。您将注意到,在图1中,当一个正方形经历欧氏变换时,尺寸不会改变,平行线保持平行,并且在转换后直角保持不变。 3. 仿射(MOTION_AFFINE):仿射变换是旋转、平移(移位)、缩放和剪切的组合,该变换有六个参数。当正方形经历仿射变换时,平行线保持平行,但是以直角相交的线不再保持正交。 4. 单应性(MOTION_HOMOGRAPHY):上述所有变换都是2D变换。它们不考虑3D效果。另一方面,单应性变换可以解释一些3D效果(但不是全部)。该变换有8个参数。使用单应性转换时的正方形可以更改为任何四边形。 在OpenCV中,仿射变换参数存储在2×3大小的矩阵中。平移和欧氏变换是仿射变换的特例。在平移中,旋转,缩放和剪切参数为零,而在欧几里德变换中,缩放和剪切参数为零。因此,平移和欧氏变换也存储在2×3矩阵中。一旦估计了这个矩阵,就可以使用函数warpAffine使图像对齐。 另一方面,单应性变换参数存储在3×3矩阵中。一旦估计了单应性矩阵,就可以使用warpPerspective使图像对齐。 使用增强相关系数(ECC)最大化的图像对齐 1. 与像素强度差异的传统相似性度量不同,ECC对比度和亮度的光度失真不变。 2. 虽然目标函数是参数的非线性函数,但它们为解决优化问题而开发的迭代方案是线性的。换句话说,他们解决了一个问题在表面上计算成本昂贵的问题,并找到了一种迭代求解的简单方法。 findTransformECC OpenCV中的示例 在OpenCV 3中,使用函数findTransformECC估计ECC图像对齐的运动模型。以下是使用findTransformECC的步骤 1. 读取图像。 2. 将它们转换为灰度。 3. 选择你要估算的运动模型。 4. 分配空间(warp_matrix)以存储运动模型。 5. 定义终止条件,告诉算法何时停止。 6. 使用findTransformECC估算warp矩阵。 7. 将warp矩阵应用于其中一个图像,使其与另一个图像对齐。 让我们深入研究代码,了解如何使用它。
- # 读取要对齐的图像
- im1 = cv2.imread("images/image1.jpg");
- im2 = cv2.imread("images/image2.jpg");
- # 将图像转为灰度图像
- im1_gray = cv2.cvtColor(im1,cv2.COLOR_BGR2GRAY)
- im2_gray = cv2.cvtColor(im2,cv2.COLOR_BGR2GRAY)
- # 得到img1的大小i
- sz = im1.shape
- # 定义运动模型
- warp_mode = cv2.MOTION_TRANSLATION
- # 根据运动模型创建一个2*3或3*3矩阵
- if warp_mode == cv2.MOTION_HOMOGRAPHY :
- warp_matrix = np.eye(3, 3, dtype=np.float32)
- else :
- warp_matrix = np.eye(2, 3, dtype=np.float32)
- # 设置迭代次数.
- number_of_iterations = 5000;
- # 指定迭代递增的阈值-两个迭代之间的相关系数
- termination_eps = 1e-10;
- # 定义终止条件
- criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, number_of_iterations, termination_eps)
- # 运行ECC算法,将结果存在warp_matrix中
- (cc, warp_matrix) = cv2.findTransformECC (im1_gray,im2_gray,warp_matrix, warp_mode, criteria)
- if warp_mode == cv2.MOTION_HOMOGRAPHY :
- # 模型为单应性时用warpPerspective函数
- im2_aligned = cv2.warpPerspective (im2, warp_matrix, (sz[1],sz[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
- else :
- # 模型为平移,欧氏和仿射时用warpAffine函数
- im2_aligned = cv2.warpAffine(im2, warp_matrix, (sz[1],sz[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP);
- # 展示结果
- cv2.imshow("Image 1", im1)
- cv2.imshow("Image 2", im2)
- cv2.imshow("Aligned Image 2", im2_aligned)
- cv2.waitKey(0)
复制代码
|