《深度学习》OpenCV 摄像头OCR 过程及案例解析

目录

一、摄像头OCR

1、含义

2、一般操作步骤

1)安装OpenCV库

2)设置摄像头

3)图像采集

4)图像预处理

5)文本识别

6)文本处理

7)结果显示

二、案例实现

1、定义展示图像函数

2、定义自动缩放图片大小函数

3、定义轮廓点的排序函数

4、定义透视变换函数

5、打开相应摄像头

6、建立整体循环结构

7、执行上述代码


一、摄像头OCR

1、含义

        OpenCV摄像头OCR是一个使用OpenCV库OCR技术实现的工具,它可以通过摄像头实时读取图像,然后利用OCR光学字符识别)技术将图像中的文本内容提取出来。这个工具可以应用于各种场景,例如扫描身份证、识别车牌号、读取条形码等。使用OpenCV摄像头OCR,可以方便地在实时图像中进行文本识别和处理。

2、一般操作步骤

        1)安装OpenCV库

                首先需要安装OpenCV库,这是一个开源的计算机视觉库,提供了许多图像处理和分析的功能。

        2)设置摄像头

                将摄像头与计算机连接,并通过OpenCV库进行初始化和设置,以确保能够实时获取摄像头图像

        3)图像采集

                通过调用OpenCV库提供的函数,从摄像头中获取图像帧,并将其存储为图像对象。

        4)图像预处理

                对采集到的图像进行预处理,以提高后续的OCR识别效果。可能的预处理包括图像灰度化、二值化、降噪等。

        5)文本识别

                使用OCR技术对预处理后的图像进行文本识别。这可以使用OCR引擎,如Tesseract进行,也可以使用第三方OCR服务。

        6)文本处理

                对识别出的文本进行必要的后处理,例如去除空格、提取特定格式的信息等。

        7)结果显示

                将识别和处理后的文本结果显示在图像或图形用户界面上,以便用户查看和使用。

二、案例实现

1、定义展示图像函数

import numpy as np
import cv2def cv_show(name,img):cv2.imshow(name,img)# cv2.waitKey(60)

2、定义自动缩放图片大小函数

# 调整图像高宽,保持图像宽高比不变
def resize(image,width=None,height=None ,inter=cv2.INTER_AREA):  # 输入参数为图像、可选宽度、可选高度、插值方式默认为cv2.INTER_AREA,即面积插值dim = None   # 存储计算后的目标尺寸w、h(h,w) = image.shape[:2]  # 返回输入图像高宽if width is None and height is None:   # 判断是否指定了宽和高大小,如果没有指定则返回原图return imageif width is None:   # 判断如果没有指定宽度大小,则表示指定了高度大小,那么运行内部代码r = height/float(h)   # 指定高度与原图高度的比值dim = (int(w*r),height)   # 宽度乘以比值得到新的宽度,此处得到新的宽高else:  # 此处表示为width不是None,即指定了宽度,与上述方法一致,计算比值r = width/float(w)dim = (width,int(h*r))resized = cv2.resize(image,dim,interpolation=inter)     # 指定图像大小为上述的dim,inter默认为cV2.INTER_AREA,即面积插值,适用于缩放图像。return resized

3、定义轮廓点的排序函数

def order_points(pts):   # 对输入的四个点按照左上、右上、右下、左下进行排序rect = np.zeros((4,2),dtype='float32')   # 创建一个4*2的数组,用来存储排序之后的坐标位置# 按顺序找到对应坐标0123分别是左上、右上、右下、左下s = pts.sum(axis=1)   # 对pts矩阵的每个点的x y相加rect[0] = pts[np.argmin(s)]    # np.argmin(s)表示数组s中最小值的索引,表示左上的点的坐标rect[2] = pts[np.argmax(s)]    # 返回最大值索引,即右下角的点坐标diff = np.diff(pts,axis=1)   # 对pts矩阵的每一行的点求差值rect[1] = pts[np.argmin(diff)]   # 差值最小的点为右上角点rect[3] = pts[np.argmax(diff)]   # 差值最大表示左下角点return rect   # 返回排序好的四个点的坐标

4、定义透视变换函数

# 将透视扭曲的矩形变换成一个规则的矩阵
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)  # 根据原始点和变换后的点计算透视变换矩阵Mwarped = cv2.warpPerspective(image,M,(maxWidth,maxHeight))  # 对原始图像,针推变换矩阵和输出图像大小进行透视变换,返回变换后的图片# 返回变换后的结果return warped

5、打开相应摄像头

import cv2
cap = cv2.VideoCapture(0)   # 确保摄像头是可以启动的状态
if not cap.isOpened():   # 打开失败print("Cannot open camera")exit()

6、建立整体循环结构

while True:flag = 0  # 用于标识 当前是否检测到文档ret,image = cap.read()  # 从摄像头读取每一帧图像,如果正确读取帧,ret为True,image为读取到的帧图像orig = image.copy()   # 对每一帧做副本if not ret:   # 读取失败,则退出循环print("不能读取摄像头")breakcv_show("image",image)   # 展示读取到的帧画面gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)  # 图像处理,转换为灰度图gray = cv2.GaussianBlur(gray,(5,5), 0)  # 高斯滤波减少图像中的噪点edged = cv2.Canny(gray,75,200)  # 使用canny边缘检测算法检测图像边缘cv_show('1',edged)# 对进行处理过的图像做副本,然后进行轮廓检测,cv2.RETR_EXTERNAL表示只检测最外层轮廓,cv2.CHAIN_APPROX_SIMPLE表示只保存轮廓端点坐标,返回轮廓点的集合列表cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]# 对轮廓点进行排序,排序方式为轮廓面积的大小,以降序排列cnts = sorted(cnts,key=cv2.contourArea,reverse=True)[:3]image_contours = cv2.drawContours(image, cnts, -1, (0, 255, 0),2)  # 在原图上绘制轮廓,-1表示绘制所有轮廓cv_show( "image_contours", image_contours)k = cv2.waitKey(60)if k == 27:   # esc键的asc码为27,点击esc终止循环breakfor c in cnts:   # 遍历每一幅轮廓的描述信息# 计算轮廓近似peri = cv2.arcLength(c,True)   # 其计算轮蹦的周长,True表示封闭图像# c表示输入的点集# epsilon表示从原始轮到近似轮的最大距离,它是一个准确度参数approx = cv2.approxPolyDP(c,0.05 * peri, True)   # 轮廓近似,对待逼近的轮廓c进行多边形逼近,逼近的精度为0.05*peri,即周长的5%area = cv2.contourArea(approx)   # 计算逼近的多边形轮廓面积# 4个点的时候就拿出来if area > 20000 and len(approx) == 4:   # 筛选轮廓面积大于20000,近似多边形四个顶点,认为检测到了文档screenCnt = approx   # 将筛选出来的近似多边形赋值给screenCntflag = 1  # 将上述设置的旗帜设置为1print(peri, area)   # 打印识别出来的轮廓周长和轮廓面积print('检测到文档')breakif flag == 1:  # 如果检测到文档# 展示结果# print("STEP 2:获取轮骤")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,220,255,cv2.THRESH_BINARY)[1]# ref = cv2.threshold(warped,0, 255, CV2.THRESH BINARY | CV2.THRESH OTSU)[1]cv_show("ref",ref)cap.release()  # 释放捕获器,释放摄像头资源
cv2.destroyAllWindows()   # 关闭所有OpenCV创建的窗口

7、执行上述代码

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解 JavaScript 事件循环机制:单线程中的异步处理核心

深入理解 JavaScript 事件循环机制:单线程中的异步处理核心 JavaScript 是一门单线程的编程语言,也就是说它在同一时间只能执行一个任务。然而,现代 Web 应用经常需要处理大量的异步操作,如用户输入、网络请求、定时器等。为了确…

《迁移学习》—— 将 ResNet18 模型迁移到食物分类项目中

文章目录 一、迁移学习的简单介绍1.迁移学习是什么?2.迁移学习的步骤 二、数据集介绍三、代码实现1. 步骤2.所用到方法介绍的文章链接3. 完整代码 一、迁移学习的简单介绍 1.迁移学习是什么? 迁移学习是指利用已经训练好的模型,在新的任务上…

鸿蒙开发(NEXT/API 12)【状态查询与订阅】手机侧应用开发

注意 该接口的调用需要在开发者联盟申请设备基础信息权限与穿戴用户状态权限,穿戴用户状态权限还需获得用户授权。 实时查询穿戴设备可用空间、电量状态。订阅穿戴设备连接状态、低电量告警、用户心率告警。查询和订阅穿戴设备充电状态、佩戴状态、设备模式。 使…

初识Django

前言: 各位观众老爷们好,最近几个月都没怎么更新,主要是最近的事情太多了,我也在继续学习Django框架,之前还参加了一些比赛,现在我会开始持续更新Django的学习,这个过程会比较久,我会把我学习的…

MySQL--三大范式(超详解)

目录 一、前言二、三大范式2.1概念2.2第一范式(1NF)2.3第二范式(2NF)2.3第三范式(3NF) 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导,有什么不对的地方,我会及时改进…

嘴尚绝卤味:健康美味的双重奏

在当今快节奏的生活中,人们对美食的追求不再仅仅停留于味蕾的满足,更加注重食物的健康与营养。在这一背景下,"嘴尚绝卤味"以其独特的健康理念与精湛的制作工艺,成为了市场上备受瞩目的卤味品牌。本文将从"嘴尚绝卤…

Kotlin基本知识

Kotlin是一种现代的静态类型编程语言,由JetBrains公司在2010年推出,并被Google在2019年宣布为Android开发的首选语言。 超过 50% 的专业 Android 开发者使用 Kotlin 作为主要语言,而只有 30% 使用 Java 作为主要语言。 70% 以 Kotlin 为主要语…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑光伏不确定性的配电网谐波监测优化配置方法 》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Azure DevOps Server:不能指派新增的用户

Contents 1. 概述2. 解决方案 1. 概述 近期和微软Azure DevOps项目组解决了一个“无法指派开发人员”的问题,在此分享给大家。问题描述: 在一个数据量比较大的Azure DevOps Server的部署环境中,用户发现将新用户的AD域账户添加到Azure DevOps…

《15分钟轻松学 Python》教程目录

为什么要写这个教程呢,主要是因为即使是AI技术突起的时代,想要用好AI做开发,那肯定离不开Python,就算最轻量级的智能体都有代码块要写,所以不一定要掌握完完整整的Python,只要掌握基础就能应对大部分场景。…

数据看板如何提升决策效率?

数据看板作为一种直观、高效的数据可视化工具,在这一过程中发挥着至关重要的作用。以一家中型制造企业为例,每天面临着生产计划的安排、原材料的采购、产品质量的把控以及市场销售的策略制定等诸多业务场景。在生产线上,需要确保设备的高效运…

【隐私计算篇】多方安全计算之函数秘密共享(FSS)

1. 函数秘密共享(FSS)定义 秘密共享是一种将一个值拆分为多个份额的方法,形式有多种,可以参考《安全多方计算(MPC)矩阵乘法算子的原理分析》。这里主要提及加法秘密共享,使得:这些份额可以重新组合以还原出秘密值;任…

【HTML并不简单】笔记1-常用rel总结:nofollow、noopener、opener、noreferrer,relList

文章目录 rel"nofollow"rel"noopener"与rel"opener"rel"noreferrer"relList对象 《HTML并不简单:Web前端开发精进秘籍》张鑫旭,一些摘要: HTML,这门语言的知识体系非常庞杂,涉…

Python数据结构与算法问题详解

Python数据结构与算法问题详解 Python 作为一种高级编程语言,凭借其简洁的语法和强大的内置库,成为了数据结构与算法学习的绝佳工具。本文将深入解析几种常见的数据结构,并结合具体的算法,展示如何在实际问题中高效解决问题。通过…

《PMI-PBA认证与商业分析实战精析》第7章 解决方案评价

第7章 解决方案评价 本章主要内容: 评价的建议思维 解决方案的评价计划 确定评价什么 何时以及如何验证解决方案的结果 评价验收标准和解决缺陷 促进通过/不通过的决策 获得解决方案的签字确认 评价解决方案的长期绩效 解决方案替换/淘汰 本章涵盖的考试…

ASP.NET Core 创建使用异步队列

示例图 在 ASP.NET Core 应用程序中,执行耗时任务而不阻塞线程的一种有效方法是使用异步队列。在本文中,我们将探讨如何使用 .NET Core 和 C# 创建队列结构以及如何使用此队列异步执行操作。 步骤 1:创建 EmailMessage 类 首先&#xff0c…

1、Spring Boot 3.x 集成 Eureka Server/Client

一、前言 基于 Spring Boot 3.x 版本开发,因为 Spring Boot 3.x 暂时没有正式发布,所以很少有 Spring Boot 3.x 开发的项目,自己也很想了踩踩坑,看看 Spring Boot 3.x 与 2.x 有什么区别。自己与记录一下在 Spring Boot 3.x 过程…

Linux下的IO模型

阻塞与非阻塞IO(Input/Output) 阻塞与非阻塞IO(Input/Output)是计算机操作系统中两种不同的文件或网络通信方式。它们的主要区别在于程序在等待IO操作完成时的行为。 阻塞IO(Blocking IO) 在阻塞IO模式下…

详细介绍:API 和 SPI 的区别

文章目录 Java SPI (Service Provider Interface) 和 API (Application Programming Interface) 的区别详解目录1. 定义和目的1.1 API (Application Programming Interface)1.2 SPI (Service Provider Interface) 2. 使用场景2.1 API 的应用场景2.2 SPI 的应用场景 3. 加载和调…

PyGWalker:让你的Pandas数据可视化更简单,快速创建数据可视化网站

1、PyGWalker应用: 在数据分析的过程中,数据的探索和可视化是至关重要的环节,如何高效地将分析结果展示给团队、客户,甚至是公众,是很多数据分析师和开发者面临的挑战,接下来介绍的两大工具组合——PyGWalker与Streamlit,可以帮助用户轻松解决这个问题,即使没有复杂的代…