楼主: 20260_web
87 0

[图行天下] 【opencv图片倾斜矫正】 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

80%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0.0128
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
30 点
帖子
2
精华
0
在线时间
0 小时
注册时间
2018-10-30
最后登录
2018-10-30

楼主
20260_web 发表于 2025-12-5 16:57:09 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

在图像处理过程中,若经过分割后的图像存在倾斜现象,会为后续的分析与识别带来不便。因此,需要对倾斜图像进行矫正处理,使其恢复水平状态。本文介绍一种基于 OpenCV 的图像自动矫正方法,利用霍夫变换检测直线,并计算整体旋转角度,最终通过仿射变换实现图像校正。

主要处理流程如下:

  1. 使用 Canny 算子提取图像边缘;
  2. 应用霍夫变换检测图像中的直线;
  3. 筛选出可用于角度估计的直线并计算平均倾斜角;
  4. 构建旋转矩阵,将图像反向旋转至水平;
  5. 使用仿射变换完成图像矫正。

步骤一:边缘检测与直线提取

首先读取输入图像并转换为灰度图,随后使用 Canny 算法提取边缘信息:

img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
canny_img = cv2.Canny(img, 50, 200, 3)

接着调用 cv2.HoughLines 方法检测图像中所有直线。该函数返回的结果是一个包含多个 (rho, theta) 参数对的数组,其形状为 (N, 1, 2),其中 N 是检测到的直线数量。

lines = cv2.HoughLines(canny_img, rho=1, theta=np.pi/180, threshold=100)

参数说明:

  • rho:从图像左上角原点到直线的垂直距离;
  • theta:从原点引向直线的垂线与 x 轴正方向之间的夹角,顺时针方向为正。

步骤二:绘制直线并分类筛选

为了可视化每条直线,定义一个辅助函数用于根据 rho 和 theta 计算直线的两个端点:

def _compute_line_pt(rho, theta, size=(2000,2000)):
    a, b = np.cos(theta), np.sin(theta)
    x0, y0 = a * rho, b * rho
    x1 = int(x0 + size[0] * (-b))
    y1 = int(y0 + size[1] * a)
    x2 = int(x0 - size[0] * (-b))
    y2 = int(y0 - size[1] * a)
    return (x1,y1), (x2, y2)

遍历所有检测出的直线,根据 theta 值判断其方向。当 theta 接近 0 或 π/2 时,对应的是接近水平或垂直的直线。我们关注的是接近水平的线条(即 theta ∈ [π/4, 3π/4] 之外的部分),这些线条更能反映图像的整体倾斜趋势。

thetas, out_thetas = [], []
for rho, theta in lines[:, 0]:
    pt1, pt2 = _compute_line_pt(rho, theta)
    if (theta < np.pi/4) or (theta > 3*np.pi/4):
        cv2.line(img_hough, pt1, pt2, (0, 255, 0), 2)
        out_thetas.append(theta)
    else:
        thetas.append(theta)
        cv2.line(img_hough, pt1, pt2, (255, 0, 0), 2)

在结果图中,绿色线条表示被忽略的方向(非主倾斜方向),蓝色线条则用于后续角度估算。红色粗线代表最终计算得出的主要倾斜方向。

步骤三:计算平均旋转角度

将所有符合条件的蓝色直线的 theta 角度取平均值,得到图像的整体倾斜角度。由于 OpenCV 中旋转为逆时针为正,因此需对该角度取负值以实现反向旋转矫正。

步骤四:生成旋转矩阵并进行图像变换

使用 cv2.getRotationMatrix2D 函数生成二维旋转矩阵。设置图像中心为旋转中心,缩放比例保持为 1.0,避免图像变形。

h, w = img_hough.shape[:2]
c_h, c_w = h // 2, w // 2
matrix = cv2.getRotationMatrix2D((c_w, c_h), -rotation_degree, 1.0)
dst = cv2.warpAffine(img, matrix, (w,h))

步骤五:执行仿射变换完成矫正

调用 cv2.warpAffine 对原图进行旋转矫正:

rotated_img = cv2.warpAffine(
    src=img,
    M=matrix,
    dsize=(w, h),
    flags=cv2.INTER_LINEAR,
    borderMode=cv2.BORDER_CONSTANT,
    borderValue=(0, 0, 0)
)

参数解释:

  • src:输入图像(numpy 数组);
  • M:2×3 的仿射变换矩阵;
  • dsize:输出图像尺寸(宽度, 高度);
  • dst:可选输出图像;
  • flags:插值方式,默认使用双线性插值;
  • borderMode:边界填充模式;
  • borderValue:填充颜色(BGR 格式)。

最终效果展示

下图为原始倾斜图像与矫正后结果的对比:

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Open Pen Threshold Rotation constant

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
扫码
拉您进交流群
GMT+8, 2026-2-8 13:14