如何避免图像放大后关键点坐标偏移?
问题背景
源图像中的黄色区域四个角落有紫色关键点:
- 左上角:

- 右上角:

- 右下角:

- 左下角:

原始图像:
使用以下脚本将图像放大至968×712,同时对关键点坐标进行简单缩放:
import cv2 import numpy as np src_image = cv2.imread("source_image.png") src_height, src_width = src_image.shape[0:2] target_width = 968 target_height = 712 target_image = cv2.resize(src_image, (target_width, target_height)) points = [[20, 11], [11, 147], [223, 168], [232, 32]] for p in points: p[0] = round(p[0] * target_width / src_width) p[1] = round(p[1] * target_height / src_height) points = np.array(points) points = points.reshape((-1, 1, 2)) cv2.polylines(target_image, [points], True, (255, 0, 255), 1) cv2.imwrite("resized_image.png", target_image)
预期与实际结果
- 预期:图像放大后,关键点仍贴合黄色区域角落
- 实际:所有关键点向左上角偏移,右下角点缩进至黄色区域内部:

连接关键点后偏移更明显:
疑问
- 偏移的原因是什么?(源图像边长为偶数,缩放因子为整数,排除取整问题)
- 如何修正,让关键点保持在黄色区域角落?
问题分析与解决
偏移原因
OpenCV的cv2.resize函数默认采用像素中心对齐的映射逻辑,而手动计算坐标时用的是像素左上角对齐的缩放方式,两者基准点不一致导致偏移:
- 手动计算逻辑:
dst_x = src_x * scale_x,这里的src_x是像素左上角的x坐标 - OpenCV resize映射逻辑:
dst_x = (src_x + 0.5) * scale_x - 0.5,它以像素中心为基准计算目标位置,再反推最终的像素坐标
即使缩放因子是整数,这种基准点的差异也会导致边缘位置的坐标出现明显偏移。
解决方法
调整坐标计算逻辑,匹配OpenCV的resize映射规则,修改坐标计算部分的代码即可:
import cv2 import numpy as np src_image = cv2.imread("source_image.png") src_height, src_width = src_image.shape[0:2] target_width = 968 target_height = 712 # 计算缩放因子 scale_x = target_width / src_width scale_y = target_height / src_height target_image = cv2.resize(src_image, (target_width, target_height)) points = [[20, 11], [11, 147], [223, 168], [232, 32]] # 按OpenCV的像素中心对齐逻辑计算坐标 for p in points: p[0] = round((p[0] + 0.5) * scale_x - 0.5) p[1] = round((p[1] + 0.5) * scale_y - 0.5) points = np.array(points) points = points.reshape((-1, 1, 2)) cv2.polylines(target_image, [points], True, (255, 0, 255), 1) cv2.imwrite("resized_image.png", target_image)
该方法适配OpenCV所有插值方式,能确保缩放后的关键点精准贴合黄色区域角落。
内容的提问来源于stack exchange,提问作者SagRU
相关产品推荐
相关产品推荐

