图像拼接——最佳seam 1

1、能量函数

  假设有一组对齐图像: I 0 I_0 I0 I 1 I_1 I1 P P P为两幅图像的重叠区域。整幅图像(这里指的是拼接后的图像)的标签 L L L={0,1},其中0表示图像 I 0 I_0 I0,1表示图像 I 1 I_1 I1。给重叠区域的所有像素 p ∈ p\in p P P P分配一个标签(0 or 1),获得标签集: l l l={ l 1 l_1 l1, l 2 l_2 l2, …, l P l_P lP}。我们要做的是找到一组 l l l,使能量函数 E ( l ) E(l) E(l)最小:
能量函数
where: D p D_p Dp( l p l_p lp)是数据项,代表为像素 p p p分配标签 l p l_p lp的损失; S p , q S_p,_q Sp,q( l p l_p lp, l q l_q lq)是平滑项,代表为一对像素( p,q) ∈N 分配一组标签( l p l_p lp l q l_q lq) 的损失; N ⊂ N\subset N P ∗ P P * P PP像素邻域面。

数据项定义为:
在这里插入图片描述
where: μ \mu μ 代表较大的损失值; I 0 I_0 I0 ⋂ \bigcap P P P代表 I 0 I_0 I0和区域 P P P的共同边界。

平滑项定义:
在这里插入图片描述
其中:在这里插入图片描述
  式(4)是2范式,代表欧式色差距离指标,平滑项代表像素 p p p与领域中其它节点不连续的惩罚。 p p p q q q的差异越小,它们属于同一目标或者同一背景的可能性越大,对应的损失越大; p p p q q q的差异很大,则说明2个像素位于目标和背景的边缘,被分割的可能性越大,损失能量越小。

2、Perception-based seam cutting for image stitching

2.1、新的平滑项

在这里插入图片描述
(a)、Euclidean-metric(欧几里得距离)可视化能量图,(b)、(a)对应的分割缝,(c)、sigmoid-metric可视化能量图,(d)、©对应的分割缝。
注意:可视化能量图,是将平滑项计算得到的能量图(一个二维矩阵——灰度图),作伪彩色处理得到的可视化结果。具体参考

  从图(b)中可以发现, l ∗ l_* l的缝穿过了误匹配区域(图(a)中亮蓝色的线);相反,图(b)中展示地 l + l_+ l+的缝避开了误匹配区域(图(c)中红色线)。

  特别是,颜色的感知是非线性的,因为它有一个颜色识别阈值,这意味着人眼无法区分某些颜色,即使它们不同。设 τ \tau τ为阈值,对颜色辨别的感知可表示为:
在这里插入图片描述
  我们想定义一个质量指标来衡量可见色彩差异,不可见项的代价接近0,可见项的代价接近1。定义为:
在这里插入图片描述
   如何定义 τ \tau τ κ \kappa κ。在重叠区域 P P P,阈值 τ \tau τ和色差相比较,将重叠区域划分为对齐区域和非对齐区域;这和通过阈值将灰度图划分为前景图和背景图类似。所以,本文使用大律法(Otsu’s)计算适合的 τ \tau τ。另一方面, κ \kappa κ表示在 τ \tau τ 附近颜色分辨灵敏度上升的速度。设 κ \kappa κ = 1/ ϵ \epsilon ϵ ϵ \epsilon ϵ的经验值是0.06,并且 Otsu’s的 间隔 r = 0.06。

大律法算法通过设定间隔 r,将灰度区间划分为 n 分。
1、统计各灰度区间像素点的个数。
2、遍历各阈值(阈值是 灰度区间的边界值)
3、根据阈值将所有像素点分为两类:A类、B类
   计算类A的所有像素值的方差SA,计算类B中所有像素值的方差SB
    计算类A中所有像素值之和IA,计算类B中所有像素点的像素值的像素值之和IB
    计算像素值方差的加权和S=IA*SA+SB*IB
4、最小S对应的阈值,既是结果

   平滑项定义为:
在这里插入图片描述

2.2、显著性权重

在这里插入图片描述
(a)、sigmoid-metric色彩差异 能量可视化图。(b)、Euclidean-metric对应的分割缝( l ∗ l_* l)、(c)、显著性图像、(d)、sigmoid-metric对应的分割缝( l + l_+ l+)。

   上图所示, l ∗ l_* l l + l_+ l+ 的分割缝穿过误匹配区域。特别值得注意地是,对图像内容的感知是不均匀的,人眼更多地关注显著性内容。所以,显著区域的鬼影比非显著区更加明显。
   为了从观察中获益,我们定义了显著性权重:
在这里插入图片描述
   where: ω \omega ω(.)表示重叠区域 P P P的显著性平均像素值,并且归一化 W W W 到[1,2]范围,避免过度惩罚。另外,如果 p 或 q位于重叠区域 P的边界,则 W=0。
   基于视觉的能量函数被定义为:
在这里插入图片描述

3、Parallax-tolerant Image Stitching

   图像拼接并不一定需要在重叠区域完美对齐图像。当H被用于对齐大视差图像时,局部区域的尺寸和对齐质量是相互矛盾的。

   本文策略:我们首先提出了一种有效的随机算法来寻找不精确局部对齐的单应性。在这里,我们通过从大致对齐的图像中找到一个可信的接缝,并使用接缝成本对单应性进行评分,来预测单应性实现局部缝合的效果。我们开发了一种基于图形切割的缝查找方法,该方法可以通过同时考虑几何对齐和图像内容,从仅粗略对齐的图像中估计一个可信的缝。一旦我们找到了最佳单应性,我们使用它来预对齐输入图像,然后使用内容保持翘曲来细化对齐。

3.1.、Alignment Model Selection

  使用全局H寻找最佳对齐和最佳缝,再使用spatially-varying warping来进行变换。

3.2、Alignment Quality Assessment

  想要评估上文中使用混合对齐(首先使用H warp和 content-preserving
warping)拼接图的质量。可以通过比较变换图和参考图,来评估两幅图像的对齐效果。然而,这种方式在两幅图像的重叠区域,并不能稳定地预测最佳缝。另外,拼接图的图像内容效果并没有被考虑。在拼接中,像边缘这种显著性特征应该被很好地对齐;然而,类似天空这样的图像区域,并不需要非常好地对齐。最后,这种方法会非常慢,因为当我们评估随机算法内部的对齐质量时,它需要运行content-preserving
warping。

  作者方法:首先,我们通过评估图像边缘而不是原始图像,对图像对齐质量进行评价。其次,我们只评估单应性如何支持拼接。如果只需要对全局变换进行微小的调整,那么感知内容的变换是非常有效的,这可以证明这种简化是合理的。但它也带来了一个挑战:我们方法中的单应性被设计为松散的,不能准确对齐两个图像。然后,我们需要预测对齐的效果如何,才能从大致对齐的图像实现无缝拼接。我们通过从大致对齐的图像中找到一个可信的接缝,并使用接缝成本来对接缝进行评分,来解决这个问题。

  我们首先对输入图像进行下采样,以提高速度和容忍小的偏差。使用Canny边沿检测得到输入图像的边缘图。这个边缘图是低通滤波的,可以容忍小的误匹配。计算 warp edge map 和 reference image‘s edge map 的差异,得到差异图 E d E_d Ed。在差异图 E d E_d Ed中,最佳拼接缝应该避免通过大差异像素点。使用图割算法寻找最佳拼接缝。简而言之,将重叠区域的每个像素点作为一个节点。
  我们定义两个相邻像素点间 s s s t t t的边缘差异为:
在这里插入图片描述
  where:我们使用 对齐置信函数 f c ( s ) f_c(s) fc(s)加权边缘花费。计算 f c ( s ) f_c(s) fc(s)是为了进一步说明单应性只能大致对齐两幅图像,而content-preserving warping将用于细化对齐。因为只使用全局H,只能粗略配准;content-preserving warping 可以提高配准。所以要弱化仅仅使用全局H带来的误匹配。f 通过 SIFT 特征点分布情况来计算。
在这里插入图片描述
  where: P i P_i Pi是SIFT特征点的位置, P s P_s Ps是像素点 s s s的位置。 g g g是高斯函数,把SIFT特征点的效果传播到它的邻域中(平滑吧)。 δ \delta δ是一个常数,默认为0.01。

3.2.1、Homography Screening

  有些H并不会带来好的拼接结果,可以在评估它们的对齐质量之前将它们检测出来,并忽略掉。我们通过计算H如何偏离其最佳拟合相似变换来衡量单应性H变换图像I的视角失真。 C i C_i Ci表示输入图像 I I I的四个顶点坐标, C i \over{C_i} Ci C i C_i Ci H H H变换后的结果。定义最佳拟合相似变换(best-fitting similarity transformation) H s ^ \hat{H_s} Hs^
在这里插入图片描述
  得到使等式自小的 H s ^ \hat{H_s} Hs^。使用 H s ^ \hat{H_s} Hs^变换 C i C_i Ci得到新的顶点坐标 C i ^ \hat{C_i} Ci^,然后计算 C i \over{C_i} Ci C i ^ \hat{C_i} Ci^坐标点的距离差。如果使用图片尺寸归一化后的距离和大于阈值(默认为0.01),该 H H H被忽略。
1、使用 H H H计算 I I I四个顶点 C i C_i Ci的新坐标 C i \over{C_i} Ci
2、利用公式(3)得到最佳拟合相似变换 H s ^ \hat{H_s} Hs^
3、使用 H s ^ \hat{H_s} Hs^计算 I I I四个顶点 C i C_i Ci的新坐标 C i ^ \hat{C_i} Ci^
4、计算变换坐标 C i \over{C_i} Ci C i ^ \hat{C_i} Ci^ 的距离差,判断是否小于阈值 δ \delta δ

3.3. Alignment Algorithm Summary

  1. 检测和匹配输入图像的特征点(SIFT),并且计算输入图像的 edge map。
  2. 随机选择一个种子特征点,并将其空间上最近的近邻一一分组,直到所选的特征集无法匹配具有预定义阈值的单应拟合为止。我们为每个特征点维护一个惩罚值,以确定在迭代过程中它被选择的时间。当一个特征点被选中时,我们将其惩罚值增加1。在每次迭代中,要选择一个有效的种子,一个特征点之前不应该被选择为种子,并且它的惩罚分数低于所有特征点的平均惩罚值。
  3. 使用3.2节中的算法评估第2步中最佳拟合相似变换的对齐质量,如果H满足先前先前定义的质量阈值,转到第4步。否则,如果平均惩罚值很小,转到第2步。否则选择迭代过程中估计的最佳单应性,然后转到步骤4。
  4. 使用最优单应性 H H H对图像进行预对齐,并使用由所选特征点集引导的content-preserving warping 来细化对齐,如在第3.3.1节中描述。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
图像拼接最佳缝合线算法常用的是SIFT算法。以下是Python代码的示例: ```python import cv2 import numpy as np # Load the images to be stitched img1 = cv2.imread('image1.jpg') img2 = cv2.imread('image2.jpg') # Convert the images to grayscale gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # Detect the keypoints and compute the descriptors using SIFT sift = cv2.xfeatures2d.SIFT_create() kp1, des1 = sift.detectAndCompute(gray1, None) kp2, des2 = sift.detectAndCompute(gray2, None) # Match the descriptors bf = cv2.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) # Apply ratio test to filter out false matches good_matches = [] for m, n in matches: if m.distance < 0.75 * n.distance: good_matches.append(m) # Find the homography matrix src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) # Compute the size of the stitched image h, w = img1.shape[:2] h2, w2 = img2.shape[:2] pts = np.float32([[0, 0], [0, h], [w, h], [w, 0]]).reshape(-1, 1, 2) dst = cv2.perspectiveTransform(pts, M) dst = np.concatenate((pts, dst), axis=0) x, y, w, h = cv2.boundingRect(dst) max_x = max(w, w2) max_y = max(h, h2) # Create the stitched image stitched = np.zeros((max_y, max_x, 3), dtype=np.uint8) stitched[y:h+y, x:w+x] = img1 stitched[:h2, :w2] = img2 # Find the best seam line seam_mask = np.zeros((max_y, max_x, 3), dtype=np.uint8) seam_mask[y:h+y, x:w+x] = 1 gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY) sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3) sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3) mag = np.sqrt(sobelx**2 + sobely**2) mag[mag == 0] = 1e-10 gradient = sobely/mag gradient[np.isnan(gradient)] = 0 gradient[np.isinf(gradient)] = 0 gradient = np.abs(gradient) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) gradient = cv2.morphologyEx(gradient, cv2.MORPH_CLOSE, kernel) seam_mask = cv2.cvtColor(seam_mask, cv2.COLOR_BGR2GRAY) gradient = np.uint8(gradient*255) gradient = cv2.bitwise_and(gradient, gradient, mask=seam_mask) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(gradient) if max_loc[1] > h: max_loc = (max_loc[0], h-1) if max_loc[1] < 0: max_loc = (max_loc[0], 0) seam = (max_loc[0], max_loc[1]-y) # Blend the images along the seam line mask1 = np.zeros((h, w), dtype=np.float32) mask2 = np.zeros((h2, w2), dtype=np.float32) mask1[:, :seam[0]] = 1 mask2[:, seam[0]:] = 1 mask = np.zeros((max_y, max_x), dtype=np.float32) mask[y:h+y, x:w+x] = mask1 mask[:h2, :w2] += mask2 blend = cv2.seamlessClone(stitched, img2, mask, seam, cv2.MIXED_CLONE) # Show the stitched image cv2.imshow('Stitched Image', blend) cv2.waitKey(0) cv2.destroyAllWindows() ``` 该代码包括了SIFT特征点检测、特征点匹配、计算单应性矩阵、拼接图像、找到最佳缝合线以及沿缝合线混合图像的过程。需要注意的是,SIFT算法需要OpenCV的contrib模块支持,因此需要确保安装了该模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值