OpenCV技术问题:如何去除文档扫描中的凸性缺陷?
嘿,我完全懂你这个痛点——普通的透视变换确实搞不定书页的凸性变形!毕竟透视变换只能处理平面的透视偏移,而书页弯起来的那种中间凸起,属于非线性的曲面畸变,线性变换根本吃不消。结合你只有页面边界的情况,我给你一套实用的解决思路:
第一步:先做基础透视校正(把页面拉成矩形)
既然你能拿到页面边界,首先得从中提取出四个角点(如果边界是连续的曲线,可以用多边形拟合的方式找到四个顶点)。这一步先把页面的倾斜、透视偏移搞定,得到一个规整的矩形页面——虽然中间还是凸的,但这是后续校正的基础。
举个OpenCV的代码例子:
import cv2 import numpy as np # 假设你已经从边界提取到了四个角点,顺序是左上、右上、右下、左下 src_pts = np.array([[x1,y1], [x2,y2], [x3,y3], [x4,y4]], dtype=np.float32) # 设定目标矩形的尺寸,比如800x600 dst_width, dst_height = 800, 600 dst_pts = np.array([[0,0], [dst_width,0], [dst_width,dst_height], [0,dst_height]], dtype=np.float32) # 计算透视变换矩阵并应用 perspective_matrix = cv2.getPerspectiveTransform(src_pts, dst_pts) warped_img = cv2.warpPerspective(original_img, perspective_matrix, (dst_width, dst_height))
第二步:非线性校正凸性畸变
这一步是核心,我们需要用非线性变换来抵消书页的凸起。因为没有网格,我们可以利用径向收缩变换或者虚拟网格插值来实现:
方法1:径向收缩(简单易上手)
书页的凸性通常是中间区域向外鼓,我们可以让每个像素根据到中心的距离,向中心做适度收缩,以此抵消凸起。具体来说,就是给每个像素的坐标加一个与距离平方成正比的偏移:
def fix_convex_distortion(img, distortion_coeff=0.000012): h, w = img.shape[:2] center_x, center_y = w // 2, h // 2 # 生成整个图像的坐标网格 x_coords, y_coords = np.meshgrid(np.arange(w), np.arange(h)) # 计算每个点到中心的距离平方 distance_sq = (x_coords - center_x) ** 2 + (y_coords - center_y) ** 2 # 计算校正后的坐标:向中心收缩,距离越远收缩越多 corrected_x = center_x + (x_coords - center_x) * (1 - distortion_coeff * distance_sq) corrected_y = center_y + (y_coords - center_y) * (1 - distortion_coeff * distance_sq) # 转换为OpenCV需要的float32格式,用三次插值做重映射 corrected_x = corrected_x.astype(np.float32) corrected_y = corrected_y.astype(np.float32) final_img = cv2.remap(img, corrected_x, corrected_y, cv2.INTER_CUBIC) return final_img # 调用函数,调整distortion_coeff直到凸性消除(范围大概在0.000005到0.00002之间) corrected_img = fix_convex_distortion(warped_img, distortion_coeff=0.000012)
方法2:虚拟网格插值(更精准)
如果你想要更精准的效果,可以自己生成虚拟网格:在透视校正后的矩形上,画均匀的网格线,然后把中间的网格点向中心偏移(偏移量和到中心的距离成正比),再用薄板样条插值(TPS)或者双三次插值来变换整个图像。这种方法的好处是可以更灵活地控制变形,但代码稍微复杂一点。
为什么透视变换没用?
补充一句:透视变换是线性 projective 变换,只能处理平面在相机投影下的变形(比如倾斜的页面拉正),但书页的凸性是物理弯曲导致的非线性畸变,每个像素的偏移量不是线性的,所以必须用非线性变换来校正。
内容的提问来源于stack exchange,提问作者hosh0425
相关产品推荐
相关产品推荐

