[Bugfix] 修复 Perspective 投影类的纵横比计算错误及边缘伪影 Fix geometric distortion and edge artifacts in Perspective projection #50
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem:
hFOV(and consequentlyh_len) using linear scaling based on the aspect ratio:self.hFOV = (float(self._height) / self._width) * FOV. In perspective projection, the relationship between FOV and image dimension is non-linear (tangent function). This linear approximation caused vertical squashing/stretching when the image aspect ratio was not 1:1.cv2.BORDER_WRAPincv2.remapcaused pixel bleeding from the opposite side of the image at the edges, which is incorrect for perspective images (unlike equirectangular ones).Evidence:
For a 1024x512 image (2:1 ratio) with 90° horizontal FOV:
h_len≈ 0.414 (corresponding to ~45° vertical FOV).h_len= 0.5 (corresponding to ~53.1° vertical FOV).This fix ensures square pixels are maintained regardless of the input resolution.
Fix:
__init__to calculatew_lenandh_lenusingnp.tan, strictly following the perspective projection geometry.wFOVandhFOVattributes to maintain backward compatibility.cv2.remapborder mode tocv2.BORDER_CONSTANT(black padding) to eliminate edge artifacts.问题描述 (Problem):
几何畸变 (Geometric Distortion):
原代码在计算
hFOV(以及随后的h_len)时,错误地使用了基于长宽比的线性缩放:self.hFOV = (float(self._height) / self._width) * FOV。在透视投影 (Perspective Projection) 中,FOV 与图像尺寸的关系是非线性的(正切函数关系)。这种线性近似会导致当输入图像长宽比不是 1:1 时,输出图像在垂直方向上出现挤压或拉伸(像素非正方形)。
边缘伪影 (Edge Artifacts):
cv2.remap中使用了cv2.BORDER_WRAP模式。这对于全景图是正确的,但对于透视图像(Perspective Image),会导致边缘处错误地卷绕并采样图像另一侧的像素,产生杂色伪影。验证证据 (Evidence):
以 1024x512 (2:1 长宽比) 的图像为例,设定水平 FOV 为 90°:
h_len≈ 0.414 (对应垂直 FOV ≈ 45°)。这是错误的,导致像素被压扁。h_len= 0.5 (对应垂直 FOV ≈ 53.1°)。这符合物理光学的正切投影规律,保证了像素是正方形 (Square Pixels)。修复内容 (Fix):
__init__方法:严格遵循透视投影几何,使用np.tan根据输入 FOV 和长宽比计算正确的w_len和h_len。wFOV和hFOV属性,防止破坏现有代码的兼容性。cv2.remap的边界模式改为cv2.BORDER_CONSTANT(填充黑色),消除了边缘伪影。