【问题标题】:how to rotate mutiple rectangle coordinates around image center如何围绕图像中心旋转多个矩形坐标
【发布时间】:2018-11-06 12:48:40
【问题描述】:

在测试计算机视觉算法对象检测时,通过旋转测试图像可以检测到一些遗漏的对象。通过这样做,矩形中每个点的 (x,y) 坐标表示的那些检测到的对象位置应该向后旋转。目标检测器的输出是一个 Numpy 数组,其中包含例如100 个元素,每个元素有 4 个对点,表示检测到的对象周围矩形的 (x,y) 坐标,即具有 (100,8) 形状的 Numpy 数组。这些对象是在原始图像的旋转版本中检测到的。因此,必须将它们旋转回来才能在原始图像上进行可视化。原始图像具有 5616x3744px 分辨率和旋转版本,例如90 度有 3744x5616px。

  • 每一行就像 [x1,y1,x2,y2,x3,y3,x4,y4]

问题是我们如何将所有这些点围绕图像中心旋转成一条线,让我们认为是 (2808,1872)。当我运行以下代码时,Python 会抛出 ValueError: operands could not be broadcast together with shapes (1000,8) (2,) 的错误,这是有道理的。在这种情况下,速度很重要。所以我尽量避免使用for 循环。

def Rotate2D(pts,cnt,degree):
    ang = math.radians(degree)
    '''pts = {} Rotates points(nx2) about center cnt(2) by angle ang(1) in radian'''
    return scipy.dot(pts-cnt,scipy.array([[scipy.cos(ang),scipy.sin(ang)],[-scipy.sin(ang),scipy.cos(ang)]]))+cnt

【问题讨论】:

  • @MateenUlhaq 我刚刚添加了一个 scipy 标签
  • @U8-Forward 我删除了多余的部分,但我不知道为什么要更改 1872。在我的情况下需要 1872。
  • @U8-Forward 我认为编辑出了问题,看起来像是你更改了其中一个数字。
  • @MateenUlhaq 我怎么没改号码
  • 所以,当你说 "100 个元素,每个元素有 8 个点代表 (x,y)" 你的意思是数组中的每一行包含 4 个(不是 8 个)点(即,成对的xy)例如x1y1x2y2x3y3x4y4。这是正确的吗?

标签: python image numpy scipy


【解决方案1】:

问题是您试图从(100, 8)“坐标数组”中减去“中心” - 一个二元向量。在什么空间? 8D?如果是这样,中心也应该是 8 个坐标的列表,因为 8D 空间中的点是通过提供其沿 8 个轴中的每一个轴的坐标来定义的。

如果坐标数组的形状为 (100, 2),则您的代码有效。


如果,当你说 “100 个元素,每个元素有 8 个点代表 (x,y),你的意思是数组中的每一行包含 4 个(不是 8 个)点(即,@ 987654324@ 和y) 比如x1, y1, x2, y2, x3, y3, x4, y4, 那么最好的办法就是这样处理重塑您的 pts 数组:

import numpy as np
def Rotate2D(pts, cnt, degree):
    ang = math.radians(degree)
    m = scipy.array([[scipy.cos(ang), scipy.sin(ang)],
                     [-scipy.sin(ang), scipy.cos(ang)]])
    rpts = scipy.dot(np.reshape(pts, (pts.size // 2, 2)) - cnt, m) + cnt
    rpts = np.reshape(rpts, pts.shape)

【讨论】:

  • 它们需要在图像的 2D 空间中旋转。我已经更新了我的问题。你可以检查一下。我想现在很清楚问题是什么。如何将 center.x 和 center.y 图像重塑为 8D 空间?
  • 非常感谢。有效。但是,在应用此函数之前需要减去 center.x 和 center.y,然后添加新的 center.x 和 center.y。我将把完整的解决方案放在下面。再次感谢伙计! :)
  • @MajidAzimi 你是什么意思你“在应用这个函数之前需要减去center.xcenter.y?你看到参数cnt 以及它在做什么吗?我使用了相同的变量名称cnt(与更人性化的名称相反,例如center),因为这就是您在示例中调用它的方式(!)。
  • 我已经解释了为什么要更改它。也许我做错了,我没有注意到cnt。请考虑所有的 Xs 和 Ys 都应该减去宽度和高度以移动到中心。然后这些点应该加上原始图像的宽度和高度。我认为这个问题是由于我的解释不当造成的。我会立即更新问题。请通读上面解决方案中的我的 cmets,如果它们有意义,请相应地编辑您的解决方案。然后我会删除我的。再次感谢您帮助回答这个问题,如果我的所作所为让您不高兴,我们深表歉意:)
【解决方案2】:

在@AGNGazer 的帮助下,这个问题得到了解答。 首先需要将所有点移动到中心附近:[0, 0] 为了简单和 90 度旋转,让我们考虑 2 个对象而不是 100 个对象。

old_coord = np.zeros((2,8))
old_coord [0] = [500, 500, 510, 500, 510, 510, 500, 510] # only filling one is enough to show the functionality.

使用旋转的图像中心 [1872,2808] 移动到中心。

old_coord [:, list(range(0, 8, 2))] -= 1872
old_coord [:, list(range(1, 8, 2))] -= 2808

应用 @AGNGazer 的功能。

new_coord = Rotate2D(old_coord, [0, 0], 90)

转移到原始图像中心 [1872, 2808]

new_coord [:, list(range(1, 8, 2))] += 1872
new_coord [:, list(range(0, 8, 2))] +=  2808
>>> new_coord
array([[5116.,  500., 5116.,  510., 5106.,  510., 5106.,  500.],
   [0.,  0., 0.,  0., 0.,  0., 0.,  0.]])

【讨论】:

  • 我很失望,真的。我完全按照您的要求进行了操作(旋转多个坐标),并且我的代码包括矩阵乘法之前的坐标移位 - 请参见倒数第二行 (rpts = scipy.dot(np.reshape(pts, (pts.size // 2, 2)) - cnt, m) + cnt)。您只需调用我的函数并提供坐标new_coord = Rotate2D(old_coord, [1872, 2808], 90)。你似乎在做的实际上是错误地使用了我的代码,然后试图从外部修复它并假装你已经改进了一些东西。
  • @嗨 AGN Gazer,对不起,我没有任何意思。我刚刚注意到您发送的代码中存在一个问题,这不是您这边的问题,而是由于我的解释不佳。我删除了解决方案的标签并标记了您的解决方案和最终解决方案。但是,请编辑您的解决方案以使其完全准确。让我解释一下是什么问题。也许我弄错了,您的代码已经正确。好吧,在我的情况下,我将图像旋转了 90 度并检测到了一些对象,然后我需要旋转那些检测到的边界框以显示原始图像中的对象位置。请参阅下面的评论跨度>
  • 关键是那些x1y1..x4y4坐标应该首先通过减去旋转图像的宽度和高度来转换到图像中的中心点(0,0),然后再旋转。旋转后,应使用新的中心图像坐标(即原始图像的宽度和高度)将它们平移回来。我想请您在您的解决方案中考虑这些要点。然后我将删除我的解决方案。再次抱歉:)
猜你喜欢
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 2013-08-23
相关资源
最近更新 更多