机器学习:opencv--摄像头OCR

目录

前言

一、三个函数

1.显示图像

2.点排序

3.透视变换

二、代码实例

1.打开摄像头

2.图像预处理

3.检测特定轮廓

4.对轮廓进行处理

5.释放资源


前言

        摄像头OCR指的是利用摄像头捕捉图像中的文字信息,并通过光学字符识别(OCR)技术将其转换为可编辑的文本。

 

一、三个函数

1.显示图像

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(60)

 

2.点排序

接收传入的坐标(为轮廓的四个顶点),

  1. 对每一行进行求和,
    1. 最小值是该轮廓的左上角,
    2. 最大值是右下角,
  2. 对每一行进行求差,
    1. 最小的是右上角,
    2. 最大的是右下角,
  3. 按照左上,右上,右下,左下的顺序填入rect矩阵
def order_points(pts):
    # 共4个坐标点
    rect = np.zeros((4, 2), dtype="float32")  # 用来存储排序之后的坐标位置
    # 按顺序找到对应坐标 0 1 2 3 分别是左上,右上,右下,左下
    s = pts.sum(axis=1)  # 对pts矩阵的每一行进行求和操作。 (x+y)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]
    diff = np.diff(pts, axis=1)  # 对pts矩阵的每一行进行求差操作。(y-x)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]
    return rect

 

3.透视变换

  1. 获取排序之后的点坐标
  2. 计算该轮廓的宽和高的较大值,当做变换之后的图像宽高
  3. 通过cv2.getPerspectiveTransform方法计算透视变换矩阵
  4. 再通过cv2.warpPerspective方法获取透视变换之后的图像
def four_point_transform(image, pts):
    # 获取输入坐标点
    rect = order_points(pts)
    (tl, tr, br, bl) = rect

    # 计算输入的w和h的值  欧式距离公式
    widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
    widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
    maxWidth = max(int(widthA), int(widthB))

    heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
    heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
    maxHeight = max(int(heightA), int(heightB))

    # 变换后对应坐标位置
    dst = np.array([[0, 0], [maxWidth - 1, 0],
                    [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1]], dtype="float32")
    # 计算透视变换矩阵
    M = cv2.getPerspectiveTransform(rect, dst)
    # 应用透视变换
    warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))  # 返回变换后结果
    return warped

 

二、代码实例

1.打开摄像头

  • 参数为0 则用电脑自带摄像头
  • 参数为1 则用外接摄像头
  • 若摄像头未被打开则输出Cannot open camera
cap = cv2.VideoCapture(0)  # 确保摄像头是可以启动的状态  电脑自带摄像头用0 外接的用1
if not cap.isOpened():
    print("Cannot open camera")
    exit()

 

2.图像预处理

  1. 打开摄像头之后,读取每一帧的画面并显示
  2. 转换成灰度图,进行高斯滤波处理,
  3. 然后使用Canny算子进行边缘检测并显示,
  4. 再对边缘检测之后的图像进行轮廓检测,
  5. 只取轮廓大小前十的轮廓将其画出来,并显示
while True:
    flag = 0  # 标识符 当前是否检测到文档
    ret, image = cap.read()
    orig = image.copy()
    if not ret:
        print('不能读取摄像头')
        break
    cv_show('image', image)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    edged = cv2.Canny(gray, 75, 200)
    cv_show('1', edged)

    cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]

    cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:10]
    image_contours = cv2.drawContours(image, cnts, -1, (0, 255, 0), 2)
    cv_show('image_contours', image_contours)

输出:

 

3.检测特定轮廓

  1. 遍历上述获取的轮廓 
  2. 对轮廓进行近似处理,并获取其特征点集
  3. 判断轮廓面积大于20000 并且特征点集只有4个
    for c in cnts:
        peri = cv2.arcLength(c, True)  # 计算轮廓的周长
        # True表示是否选择封闭轮廓
        approx = cv2.approxPolyDP(c, 0.05 * peri, True)  # 返回轮廓点集
        area = cv2.contourArea(approx)

        if area > 20000 and len(approx) == 4:
            screenCnt = approx
            flag = 1
            print(peri, area)
            print('检测到文档')
            break

 

4.对轮廓进行处理

  1. 如果在画面中获取到了符合条件的轮廓
  2. 就在原图上画出该轮廓
  3. 并将该轮廓图像进行透视变换并显示
  4. 最后对其进行二值化处理并显示
    if flag == 1:
        image_contours = cv2.drawContours(image, [screenCnt], 0, (0, 255, 0), 2)
        cv_show('image', image_contours)

        warped = four_point_transform(orig, screenCnt.reshape(4, 2))
        cv_show('warped', warped)

        warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
        ref = cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        cv2.imshow('ref', ref)
        cv2.waitKey(0)
输出:

 

5.释放资源

  • 最后循环结束之后记得释放资源
cap.release()  # 释放捕获器
cv2.destroyAllWindows()  # 关闭图像窗口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/886823.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习----------------------------编码器、解码器架构

目录 重新考察CNN重新考察RNN编码器-解码器架构总结编码器解码器架构编码器解码器合并编码器和解码器 重新考察CNN 编码器:将输入编码成中间表达形式(特征) 解码器:将中间表示解码成输出。 重新考察RNN 编码器:将文…

CSS 盒子属性

1. 盒子模型组成 1.1 边框属性 1.1.1 四边分开写 1.1.2 合并线框 1.1.3 边框影响盒子大小 1.2 内边距 注意: 1.3 外边距 1.3.1 嵌套块元素垂直外边距的塌陷 1.4 清除内外边距 1.5 总结

EasyExcel使用介绍

EasyExcel使用 1、EasyExcel介绍 1.1 官网介绍 传统操作Excel大多都是利用Apach POI进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多的缺陷: 动态操作Excel非常繁琐,对于新手来说,很难在短时间内上手;读写时需要占用…

二叉树深度学习——将二叉搜索树转化为排序的双向链表

1.题目解析 题目来源:LCR 155.将二叉搜索树转化为排序的双向链表 测试用例 2.算法原理 首先题目要求原地进行修改并且要求左指针代表前驱指针,右指针代表后继指针,所以思路就是 1.使用前序遍历创建两个指针cur、prev代表当前节点与前一个节点…

Stable Diffusion绘画 | 来训练属于自己的模型:炼丹参数调整--步数设置与计算

要想训练一个优质的模型,一定要认识和了解模型训练中,参数的作用和意义。 整个模型训练的过程,参数并不是一成不变的,也没有固定的模板, 当我们修改了模型训练里面的某个参数,很可能就需要连带其他一系列…

在LabVIEW中如何读取EXCEL

在LabVIEW中读取Excel文件通常使用“报告生成工具包”(Report Generation Toolkit)。以下是详细步骤: ​ 安装工具包:确保已安装“报告生成工具包”。这通常随LabVIEW一起提供,但需要单独安装。 创建VI: 打…

java入门基础(一篇搞懂)

​ 如果您觉得这篇文章对您有帮助的话 欢迎您分享给更多人哦 感谢大家的点赞收藏评论,感谢您的支持!!! 首先给大家推荐比特博哥,java入门安装的JDk和IDEA社区版的安装视频 JDK安装与环境变量的配置 IDEA社区的安装与使…

自然语言任务规划的新篇章:AutoGPT+P的突破

人工智能咨询培训老师叶梓 转载标明出处 尽管LLMs在自然语言处理(NLP)方面取得了显著进展,但它们在直接将自然语言指令转换为执行机器人任务的计划方面仍存在限制。这些限制主要源于LLMs在推理能力上的不足。由德国卡尔斯鲁厄理工学院&#…

Geogebra中级篇003—几何对象之点与向量

本文概述了在GeoGebra中如何使用笛卡尔或极坐标系输入点和向量。用户可以通过指令栏输入数字和角度,使用工具或指令创建点和向量。在笛卡尔坐标系中,示例如“P(1,0)”;在极坐标系中,示例如“P(1;0)”或“v(5;90)”。文章还介绍了点…

Spark SQL分析层优化

导读:本期是《深入浅出Apache Spark》系列分享的第四期分享,第一期分享了Spark core的概念、原理和架构,第二期分享了Spark SQL的概念和原理,第三期则为Spark SQL解析层的原理和优化案例。本次分享内容主要是Spark SQL分析层的原理…

828华为云征文|华为云 Flexus X 实例之家庭娱乐中心搭建

话接上文《828华为云征文|华为云Flexus X实例初体验》,这次我们利用手头的 Flexus X 实例来搭建家庭影音中心和密码管理环境。 前置环境 为了方便小白用户甚至运维人员,我觉得现阶段的宝塔面板 和 1Panel 都是不错的选择。我这里以宝塔为例…

《软件工程概论》作业一:新冠疫情下软件产品设计

课程说明:《软件工程概论》为浙江科技学院2018级软件工程专业在大二下学期开设的必修课。课程使用《软件工程导论(第6版)》(张海藩等编著,清华大学出版社)作为教材。以《软件设计文档国家标准GBT8567-2006》…

加密与安全_TOTP 一次性密码生成算法

文章目录 PreTOTP是什么TOTP 算法工作原理TOTP 生成公式TOTP 与 HOTP 的对比Code生成TOTP验证 TOTP使用场景小结 TOTP 与 HOTP 的主要区别TOTP 与 HOTP应用场景比较TOTP 与 HOTP安全性分析 Pre 加密与安全_HTOP 一次性密码生成算法 https://github.com/samdjstevens/java-tot…

基于Springboot vue应急物资供应管理系统设计与实现

博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…

剖解最小栈

最小栈 思路: 1. 首先实例化两个栈,分别是stack用于存放数据,minstack用于存放最小值 2. 将第一个元素压入两个栈中,判断此时若minStack栈中为空,则表示压入的为第一个数据 if ( minStack.empty () ) { minStack.pus…

【GT240X】【04】你必须知道的 50 多个 Linux 命令

文章目录 一、介绍二、五十个linux命令一览表三、50个命令详解四、结论 你必须知道的 50 多个 Linux 命令 一、介绍 你经常使用 Linux 命令?今天,我们将介绍 50 多个你必须知道的 Linux 命令。下面列出的命令是一些最有用和最常用的 Linux 命令&#x…

IDEA 最新版创建 Sping Boot 项目没有 JDK8 选项的解决方案

问题 今天新建一个 Java 项目写 demo 时,发现 Idea 上只能勾选 Java 17、21、23 三个版本 解决方案 IDEA 页面创建 Spring 项目,其实是访问 spring initializr 去创建项目。我们可以通过阿里云国服去间接创建 Spring 项目。服务器 URL 地址替换为 ht…

蓝桥杯【物联网】零基础到国奖之路:十四. 扩展模块之温湿度传感器

蓝桥杯【物联网】零基础到国奖之路:十四. 扩展模块之温湿度传感器 第一节 硬件解读第二节 CubeMX配置第三节 模版代码 第一节 硬件解读 STS3x-DIS是sensirion新一代温湿度传感器。精度较高,速度较快。SHT3x内部集成了湿度传感器和温度传感器,ADC采样输入…

[网络]抓包工具介绍 tcpdump

一、tcpdump tcpdump是一款基于命令行的网络抓包工具,可以捕获并分析传输到和从网络接口流入和流出的数据包。 1.1 安装 tcpdump 通常已经预装在大多数 Linux 发行版中。如果没有安装,可以使用包管理器 进行安装。例如 Ubuntu,可以使用以下…

9-贪心算法

参考:代码随想录 题目分类大纲如下: 贪心算法理论基础 什么是贪心? 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 贪心的套路(什么时候用贪心) 贪心算法并没有固定的套路,说白了…