4

我正在尝试确定两个图像之间的转换(旋转+平移+缩放)以移动它们。

这些图像是用两种不同的方式拍摄的,它们会产生非常不同的纹理。所以我不能使用基于保持光流的技术。我认为对图像进行阈值提取以提取几何图形会很好(参见下面的示例)。但后来我看不出我能做什么......也许提取垂直线和中心圆来帮助我提取我的转换。

我在 python 中工作,我研究了 Opencv 可以提供什么,但目前几乎没有成功。

在此处输入图像描述

--- 稍后编辑 ---

我用霍夫变换检测到圆和线(见下图)。实际上,这将有助于正确注册。但是,我可以使用 Python 上的什么工具来注册这些元素?我经常使用光流守恒,但在这种情况下它相当复杂......

在此处输入图像描述

4

3 回答 3

4

找到至少 4 个非共线对应点:

  1. 磁盘中心
  2. 在边线上找到距离磁盘中心最近的点(至少会计算 2 个对应点)。它在垂直于通过磁盘中心的边线的线上(使用此方法)。
  3. 通过磁盘中心找到侧线的平行线(可能会有所帮助)并计算该线与磁盘区域的交点(可能会有所帮助)

然后你可以使用findHomography来计算 Homography 矩阵,它是两个图像之间的转换。

示例代码类似于以下代码:

# Read the first image.
im_fst = cv2.imread('img1.jpg')
# Four points in the first image (more is better)
pts_fst = np.array([[141, 131], [480, 159], [493, 630],[64, 601]])
 
# Read the second image.
im_scd = cv2.imread('img2.jpg')
# Four points in the second image
pts_scd = np.array([[318, 256],[534, 372],[316, 670],[73, 473]])
 
# Calculate Homography
h, status = cv2.findHomography(pts_fst, pts_scd)
     
# Warp source image to destination based on homography
im_out = cv2.warpPerspective(im_fst, h, (im_scd.shape[1],im_scd.shape[0]))
于 2019-11-03T07:23:00.250 回答
2

如果模式始终是通道内的磁盘,并且具有干净的二值化,这看起来是一个简单的问题。

您可以可靠而准确地获得磁盘中心和面积,从而获得半径。从侧面的斑点中,您可以找到垂直线(霍夫,或适合轮廓内部的线,或仅穿过成对的远点)。

然后你从半径的比率或线之间的距离比率中得到比例。旋转角度由垂直方向给出。并由中心坐标平移。

实际上,对于 4 DOF,您有太多数据要解决,并且有几种可能的解决方案。根据这些图像的生成方式,您应该使用最可靠的信息。

在此处输入图像描述

于 2019-10-27T20:29:30.190 回答
1

我有一个与您非常相似的问题,试图在 CT 和 MR 图像中居中圆形物体 - 并通过配准、霍夫变换等走各种路线。所有这些都有效,但缓慢而复杂,而且不是非常强大。

通过退后一步并以不同的方式思考,我最终使用了一种更简单、更强大、更快的方法。

您在图像中有两个圆圈,并且您想要找到位置和比例。

  1. 因此,首先获取图像的两个 1D 配置文件 - 一个在行中,一个在列中。您的对象是一个圆圈,因此将产生两个类似高斯的一维轮廓。这是简单的平均数组切片,所以非常快:
    # r/c 1/0 are variables you can use to set limits on which areas of
    # the image you want to limit the search to, or you can use the entire
    # image size
    r0 = c0 = 0
    r1, c1 = image.shape
    r_prof = np.mean(image[r0:r1, :], axis=0)
    c_prof = np.mean(image[:, c0:c1], axis=1)
  1. 找到这些高斯轮廓的中心点。这对于任何峰值查找算法都很容易。这给了你你的圈子的中心。
    # find_peak is a function to find the peak index in a profile
    circle_r = find_peak(r_profile)
    circle_c = find_peak(c_profile)
  1. 要找到比例,您需要找到圆圈的大小。要做到这一点,只需重新制作图像配置文件,但这次将行/列缩小到您上方圆圈中心的单个像素。这会给你一个非常方形的轮廓。
    # get single pixel width profile across center of circle
    r_prof = np.mean(image[circle_r, :], axis=0)
    c_prof = np.mean(image[:, circle_c], axis=1)
  1. 从方形轮廓很容易计算边缘,两条边缘位置之间的差异为您提供直径。

因此,您最终得到圆的中心和直径。

我使用这种方法来做你正在做的事情——圆形轮廓的位置和大小——在 CT 和 MR 中。它最终比其他任何东西都快了至少一个数量级,而且更加强大。

于 2019-11-15T21:15:02.330 回答