基于图像opencv2/py中的anchor计算变换
Calculate transformation based on anchor in image opencv2 / py
我想根据图像中的锚点计算变换矩阵(旋转、缩放和平移)。
我的图像是一张标签图片,它始终包含一个数据矩阵。
我使用 third-party 库来检测数据矩阵。
然后,我得到它的大小、方向(使用 cv2.minAreaRect(dm_contour)
的结果)和位置。
我用这些参数构建了我称之为 "anchor" 的东西。
在第二步中,我得到了我所谓的作业,它由用户定义的 ROI 和用户定义 ROI 的图片的锚点组成。
通过这几个步骤,如果它只有平移(向左、向右、顶部、底部移动),我可以根据新标签上下文正确放置我的 ROI。
但是当我尝试替换旋转标签上的 ROI 时,它不起作用。
如果我认为我的问题出在我的旋转矩阵和整个 "translate to origen and back to position" 过程上。但是我找不到我做错了什么......
我转换 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 样本:
在此先感谢您的帮助,
所以,
我什至不知道是否有人花时间阅读我的问题,但如果它有任何帮助,这就是我所做的。
在我的第一个代码版本中,我尝试计算以下转换矩阵:
- 平移矩阵'T'
- 旋转'R'
- 缩放'S'
但是少了两个:
- 纯粹 X 'ShX'
- 纯粹的 Y 'ShY'
我的第一个第二个版本看起来像 roi_pos = ShX @ ShY @ S @ T @ T_to_pos @ R @ T_to_origin @ item_roi
结果非常笨拙,我用我的模型定义的投资回报率没有正确定位在我的测试样本上。但轮换是正确的,投资回报率会以某种方式接近预期结果。
然后我考虑优化我的 Datamatrix 检测,所以我不厌其烦地实现了我自己的 python/numpy/openCV 版本的 DM 检测算法。
锐利的 DM 检测帮助我更好地评估了我的方向和比例参数,但 ROI 仍然很低。
所以我发现了单应性,这正是我想要的。
它在已知计划中获得积分,在目标计划中获得相同积分。然后计算两个计划之间发生的转换。
有了这个矩阵 'H',我知道可以做到 roi_pos = H @ item_roi
更准确。
就这些了,希望对你有帮助,
我想根据图像中的锚点计算变换矩阵(旋转、缩放和平移)。
我的图像是一张标签图片,它始终包含一个数据矩阵。
我使用 third-party 库来检测数据矩阵。
然后,我得到它的大小、方向(使用 cv2.minAreaRect(dm_contour)
的结果)和位置。
我用这些参数构建了我称之为 "anchor" 的东西。
在第二步中,我得到了我所谓的作业,它由用户定义的 ROI 和用户定义 ROI 的图片的锚点组成。
通过这几个步骤,如果它只有平移(向左、向右、顶部、底部移动),我可以根据新标签上下文正确放置我的 ROI。
但是当我尝试替换旋转标签上的 ROI 时,它不起作用。
如果我认为我的问题出在我的旋转矩阵和整个 "translate to origen and back to position" 过程上。但是我找不到我做错了什么......
我转换 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 样本:
在此先感谢您的帮助,
所以,
我什至不知道是否有人花时间阅读我的问题,但如果它有任何帮助,这就是我所做的。
在我的第一个代码版本中,我尝试计算以下转换矩阵:
- 平移矩阵'T'
- 旋转'R'
- 缩放'S'
但是少了两个:
- 纯粹 X 'ShX'
- 纯粹的 Y 'ShY'
我的第一个第二个版本看起来像 roi_pos = ShX @ ShY @ S @ T @ T_to_pos @ R @ T_to_origin @ item_roi
结果非常笨拙,我用我的模型定义的投资回报率没有正确定位在我的测试样本上。但轮换是正确的,投资回报率会以某种方式接近预期结果。
然后我考虑优化我的 Datamatrix 检测,所以我不厌其烦地实现了我自己的 python/numpy/openCV 版本的 DM 检测算法。 锐利的 DM 检测帮助我更好地评估了我的方向和比例参数,但 ROI 仍然很低。
所以我发现了单应性,这正是我想要的。 它在已知计划中获得积分,在目标计划中获得相同积分。然后计算两个计划之间发生的转换。
有了这个矩阵 'H',我知道可以做到 roi_pos = H @ item_roi
更准确。
就这些了,希望对你有帮助,