【项目实训】成绩识别录入系统--opencv实现图片矫正 (一)

该博客介绍了如何使用Python的OpenCV库进行表格照片的图像校正,重点在于透视变换的应用。首先对图像进行灰度处理、高斯模糊和膨胀操作以获取轮廓,然后找到最大面积的外轮廓。接下来,通过轮廓检测和处理,确定表格的四个角点,以进行透视变换。博主分享了代码片段来演示如何识别和选择长方形的边线,最后讨论了OpenCV中仿射变换和透视变换的函数,计划使用透视变换处理图片。
摘要由CSDN通过智能技术生成

近期任务

实现对表格照片内容的识别算法。
我的分工:利用python的opencv库实现对照片中的表格的校正,并与小组成员进行代码整合与测试。


一、初步分析

拍照时因为镜头角度等原因,容易导致图像出现倾斜、变形等情况,为了方便后续处理我们常常需要进行图像矫正,其中主要技术原理是两种变换类型–仿射变换(Affine Transformation)和透视变换(Perspective Transformation)。本程序主要使用opencv技术实现图像识别之前的透视变换。

二、思路与部分代码

首先对图像做简单处理方便得到轮廓:

# 灰度
img = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
black = np.zeros(img.shape, np.uint8)
# 高斯模糊
img = cv2.GaussianBlur(img, (5, 5), 0, 0)
# 膨胀
element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img = cv2.dilate(img, element)

# 轮廓
img = cv2.Canny(img, 20, 40, 3)

# 外轮廓
img, contours, hierarchy = cv2.findContours(
    img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)


# 最大面积的外轮廓
max_area = 0
index = 0
for i in range(0, len(contours)):
    ps = contours[i].reshape(len(contours[i]), 2)
    r = cv2.boundingRect(ps)
    # print r
    temparea = r[2] * r[3]
    if temparea > max_area:
        index = i
        max_area = temparea

ct1 = contours[index]

通过轮廓得到顶点,难点是如何选出长方形四个角点

部分代码如下:

# 1.合并线,2.找距离很近的线
lines = []
fclock = [False]
if len(contours2) != 4:

    hull = cv2.convexHull(contours2, clockwise=5)
    # c4 = contours2.reshape(len(contours2), 2)
    c4 = hull.reshape(len(hull), 2)
    lines = pstolines(c4)
    drawlines(img.shape, lines)
    lines = removebadline(lines)
    drawlines(img.shape, lines)

    if len(lines) != 4 and len(lines) != 0:
        lines = removemoreline(lines, fclock)
        print
        "fclock=", fclock
    if len(lines) != 4 and len(lines) != 0:
        fclock = [False]
        lines = hulllines(lines)
        lines = removemoreline(lines, fclock)

if len(lines) != 4 and len(lines) != 0:
    for i in range(0, len(lines)):
        cv2.circle(black, (lines[i][0], lines[i][1]), 3, (128), 2)
        cv2.line(black, (lines[i][0], lines[i][1]), (lines[i][2], lines[i][3]), (128), 1)
        cv2.putText(black, str(i), (lines[i][0], lines[i][1]),
                    cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))
        #cv2.imshow("2", black)

    cv2.circle(black, (lines[len(lines) - 1][0],
                       lines[len(lines) - 1][1]), 3, (128), 2)
    cv2.putText(black, str(len(lines)), (lines[len(lines) - 1][0], lines[len(lines) - 1][1]),
                cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))

透视变换技术学习

摘自百度百科:
透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。

经过了解:
在OpenCV中,仿射变换和透视变换均有封装好的函数,分别为

void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

两种变换函数形式完全相同

参数InputArray src:输入变换前图像
参数OutputArray dst:输出变换后图像,需要初始化一个空矩阵用来保存结果,不用设定矩阵尺寸
参数InputArray M:变换矩阵,用另一个函数getAffineTransform()计算
参数Size dsize:设置输出图像大小
参数int flags=INTER_LINEAR:设置插值方式,默认方式为线性插值

仿射变换以3个点为基准点,即使数组长度为4也仅取前3个点作为基准点;透视变换以4个点为基准点,两种变换结果不相同。

目前计划使用透视变换处理图片。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值