用圆和线计算变换

2024-04-24 13:00:44 发布

您现在位置:Python中文网/ 问答频道 /正文

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

这些图像是用两种不同的方式拍摄的,它们产生了截然不同的纹理。所以我不能使用基于维持光流的技术。我认为最好对图像设置阈值以提取几何图形(见下面的示例)。但是我很难看到我能做什么…也许提取垂直线和中心圆来帮助我提取我的转换。在

我在python工作,我研究了Opencv可以提供的功能,但是目前还没有成功。在

enter image description here

---稍后编辑---

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

enter image description here


Tags: 工具图像功能编辑示例方式阈值中心
3条回答

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

  1. 磁盘中心
  2. 在边线上找到离磁盘中心最近的点(至少计算2个相应的点)。它位于与穿过磁盘中心的边线垂直的线上(使用this method)。在
  3. 找到穿过磁盘中心的边线的平行线(this可能有帮助),并计算这些线与磁盘面积的交点(this可能有帮助)

然后你可以用findHomography来计算单应矩阵,它是两幅图像之间的变换。在

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

# 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]))

如果模式总是一个通道内的磁盘,并且有干净的二进制化,这看起来是一个简单的问题。在

您可以可靠而准确地获得磁盘中心和面积,从而获得半径。从侧面的斑点,你可以找到垂直线(Hough,或是与轮廓内部部分的直线拟合,或者只是通过一对对遥远的点的直线)。在

然后从半径的比值,或者直线之间的距离之比得到比例。旋转角度由垂直方向给出。以及中心坐标的平移。在

实际上,你有太多的数据要解决4自由度,有几种可能的解决办法。根据这些图像是如何产生的,您应该使用最可靠的信息。在

enter image description here

我有一个和你很相似的问题,试图在CT和MR图像中居中圆形物体,并通过注册、hough变换等各种方法进行处理,这些都是可行的,但速度慢,复杂,不太健壮。在

最后,我采用了一种更简单、更健壮、更快的方法,退一步用不同的方式思考。在

你有两个圆在一个图像,你想找到位置和比例。在

  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. 找到高斯分布的中心点。这是很容易与任何峰值发现算法。这就是你的圆心。在
^{pr2}$
  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中,它的速度至少比其他任何东西都快一个数量级,而且更加坚固。在

相关问题 更多 >