【问题标题】:Calculate transformation based on anchor in image opencv2 / py基于图像opencv2/py中的anchor计算变换
【发布时间】:2020-08-13 17:07:19
【问题描述】:

我想根据图像中的锚点计算变换矩阵(旋转、缩放和平移)。

我的图像是一个标签的图片,它总是包含一个数据矩阵。 我使用第三方库来检测数据矩阵。 然后,我得到它的大小、方向(使用cv2.minAreaRect(dm_contour) 的结果)和位置。 我用这些参数构建了我所谓的“锚点”。

在第二步中,我得到了我所谓的作业,它由用户定义的 ROI 和用户定义 ROI 的图片的锚点组成。

通过这几个步骤,我可以根据新标签上下文正确放置我的 ROI,如果它只有一个转换(移动到左、右、上、下)。

但是,一旦我尝试替换旋转标签上的 ROI,它就不起作用了。

如果认为我的问题在于我的旋转矩阵和整个“转换到原点并返回到位置”过程。但我找不到我做错了什么......

我转换 ROI 位置的代码如下所示:

def process_job(anchor, img, job, file_path):
    """
    Process job file on current picture
    @param anchor = Current scene anchor
    @param img = Current picture
    @param job = Job object
    @param file_path = Job file path
    """
    print("Processing job " + file_path)
    """ Unpack detected anchor """
    a_x, a_y = (anchor[0], anchor[1])
    rotation = anchor[2]
    anchor_size = int(anchor[3])

    for item_i in job:
        item = job[item_i]
        if 'anchor' in item:
            """ Apply size rate """
            size_rate = anchor_size / int(item['anchor']['size'])
            """" Item anchor pos """
            i_a_x, i_a_y = int(item['anchor']['x']), int(item['anchor']['y'])
            """ Calculate transformation """
            """ Scaling """
            S = np.array([
                            [size_rate, 0, 0],
                            [ 0, size_rate, 0],
                            [ 0, 0, 1]
                        ])

            """ Rotation """
            angle = rotation - int(item['anchor']['o'])
            theta = np.radians(angle)
            c, s = np.cos(theta), np.sin(theta)

            R = np.array((
                        (c, s, 0),
                        (-s, c, 0),
                        (0, 0, 1)
                        ))

            """ Translation """
            x_scale = a_x - i_a_x
            y_scale = a_y - i_a_y

            T = np.array([
                            [1, 0, x_scale],
                            [0,  1, y_scale],
                            [0, 0, 1]
                        ])

            """ Shear """
            shx_factor = 0
            Shx = np.array([
                            [1, shx_factor, 0],
                            [0, 1, 0],
                            [0, 0, 1]
                        ])

            shy_factor = 0
            Shy = np.array([
                            [1,0, 0],
                            [shy_factor, 1, 0],
                            [0, 0, 1]
                        ])

            print("Scaling: " + str(size_rate) + " Rotation:" + str(angle) + " Translation:" + str((x_scale, y_scale)))
            if 'rect' in item:
                """ Unpack rectangle """
                """ (r_x1, r_y1) top-left corner """
                """ (r_x2, r_y2) bottom right corner """
                r_x1, r_y1, r_x2, r_y2 = (int(item['rect']['x1']), int(item['rect']['y1']), int(item['rect']['x2']), int(item['rect']['y2']))

                """ As np arrays """
                rect_1 = np.array([r_x1, r_y1, 1])
                rect_2 = np.array([r_x2, r_y2, 1])

                """ Translate to origen """
                T_c_1 = np.array([
                                [1, 0, -r_x1],
                                [0,  1, -r_y1],
                                [0, 0, 1]
                            ])
                """ Translate to origen """
                T_c_2 = np.array([
                                [1, 0, -r_x2],
                                [0,  1, -r_y2],
                                [0, 0, 1]
                            ])

                """ Back to postion """
                T_r1 = np.array([
                                [1, 0, r_x1],
                                [0,  1, r_y1],
                                [0, 0, 1]
                            ])

                """ Back to postion """
                T_r2 = np.array([
                                [1, 0, r_x2],
                                [0,  1, r_y2],
                                [0, 0, 1]
                            ])
                """ Apply transformations """
                final_1 =  T @ T_r1 @ R @ T_c_1 @ S @ rect_1
                final_2 =  T @ T_r2 @ R @ T_c_2 @ S @ rect_2
                x1, y1, x2, y2 = final_1[0], final_1[1], final_2[0], final_2[1]

                print("From " + str((r_x1, r_y1, r_x2, r_y2)))
                print("To " + str((int(x1), int(y1), int(x2), int(y2))))

                cv2.line(img, (int(x1), int(y1)), (int(x2), int(y2)), \
                            (0,0,0), 2)

    cv2.imwrite('./output/job.png', img)

这里是我的图片的 fex 样本:

提前感谢您的帮助,

【问题讨论】:

    标签: python-3.x opencv matrix 2d vision


    【解决方案1】:

    所以,

    我什至不知道是否有人花时间阅读我的问题,但如果它可以提供任何帮助,这就是我所做的。


    在我的第一个代码版本中,我尝试计算以下变换矩阵:

    • 平移矩阵“T”
    • 旋转“R”
    • 缩放“S”

    但是少了两个:

    • 纯粹的 X 'ShX'
    • 纯粹的“害羞”

    我的第一个第二个版本看起来像 roi_pos = ShX @ ShY @ S @ T @ T_to_pos @ R @ T_to_origin @ item_roi

    结果非常笨拙,我用模型定义的 ROI 没有正确定位在我的测试样本上。但轮换是正确的,而且 ROI 会以某种方式接近预期结果。

    然后我考虑优化我的 Datamatrix 检测,所以我费尽心思实现了我自己的 python/numpy/openCV 版本的 DM 检测算法。 锐化的 DM 检测帮助我更好地评估了我的方向和比例参数,但 ROI 仍然关闭。

    所以我发现了单应性,它正是我想要的。 它在已知计划中获取点,在目的地计划中获取相同点。然后它计算两个计划之间发生的转换。

    有了这个矩阵'H',我知道roi_pos = H @ item_roi 可以更准确。

    就是这样,希望对你有帮助,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 2013-07-30
      • 2015-12-31
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多