为何OpenCV resize指定dsize与fx/fy参数得到不同像素值?
cv2.resize两种调用方式数值差异的核心原因
该现象不是OpenCV的实现bug,而是其参数设计逻辑导致的预期行为,差异根源是两种调用方式下,最终用于插值计算的fx、fy缩放系数并不相等,即使输出尺寸完全一致。
- OpenCV内部的参数推导逻辑是固定的:
- 当你仅传入
fx/fy、dsize=None时:- 先通过内部公式
dsize = (cvRound(src.cols * fx), cvRound(src.rows * fy))计算输出尺寸,cvRound是对浮点值做四舍五入取整。 - 插值计算时,直接使用你传入的原始fx/fy值,不会根据取整后的dsize修改缩放系数。
- 先通过内部公式
- 当你仅传入
dsize、未指定fx/fy时:- 直接使用你指定的输出尺寸。
- 插值计算用的缩放系数会自动反推:
fx = (double)dsize.width / src.cols、fy = (double)dsize.height / src.rows,完全不参考你之前可能用过的原始scale值。
- 当你仅传入
- 结合你的测试用例验证:
- 输入原图为10×10,
scale=0.55:- fx分支计算输出dsize:
cvRound(10*0.55)=6,得到6×6输出,插值用的fx仍为原始值0.55。 - dsize分支传入6×6的输出尺寸后,自动反推fx = 6.0 / 10.0 = 0.6,和原始0.55存在0.05的差值。
- fx分支计算输出dsize:
- 两个分支的缩放系数不同,插值时的源坐标映射、权重分配完全不同,最终像素值自然存在差异。
- 输入原图为10×10,
- 当
scale=0.5时无差异的原因:- fx分支输出dsize为
cvRound(10*0.5)=5,得到5×5输出,插值用fx=0.5。 - dsize分支传入5×5尺寸后,反推fx=5.0/10.0=0.5,和原始fx完全一致,插值参数完全相同,结果无差异。
- fx分支输出dsize为
- 环境说明:你当前安装的多版本OpenCV(4.2.0与4.5.1)不会影响该逻辑,该参数推导规则从OpenCV 2.x版本沿用至今。
- 如果需要两种调用方式结果完全一致,可以在传入dsize时显式指定和fx分支相同的fx/fy值,例如:
resized_dsize = cv2.resize(image, (resize_width, resize_height), fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
内容的提问来源于stack exchange,提问作者Aleksey Nozdryn-Plotnicki
相关产品推荐
相关产品推荐

