【OpenCV实现图像:OpenCV进行OCR字符分割】

文章目录

    • 概要
    • 基本概念
    • 读入图像
    • 图像二值化
    • 小结

概要

在处理OCR(Optical Character Recognition,光学字符识别)时,利用传统的图像处理方法进行字符切分仍然是一种有效的途径。即便当前计算机视觉领域主导的是卷积神经网络,但对于一些相对简单的实际应用场景,传统方法仍然表现出良好的效果。

在OCR任务中,字符切分是一个关键的步骤,它能够将整个文本图像分割成单个字符,为后续的处理任务提供基础。传统图像处理方法可以通过一系列技术来实现字符的准确切分。这些技术可能包括但不限于:

边缘检测: 使用算子(如Sobel、Canny)检测图像中字符的边缘,从而确定字符的边界。连通区域分析: 通过标记和分析图像中的连通区域,可以识别字符的位置和形状。投影法: 水平和垂直投影可以帮助检测字符之间的间隔,从而进行字符切分。轮廓分析: 提取字符的轮廓信息,进而判断字符的位置和形状。形态学操作: 使用腐蚀、膨胀等形态学操作来调整字符的形状,以便更好地进行切分。

虽然卷积神经网络在图像处理任务中表现出色,但在一些简单的场景中,传统方法的实用性仍然很大。例如,在文档扫描、数字识别等任务中,通过合理运用传统图像处理技术,可以快速、准确地完成字符切分,为后续的OCR处理奠定基础。这种混合使用传统方法和深度学习技术的方式,可以充分发挥各自的优势,实现更全面、高效的图像处理任务。

基本概念

OCR(Optical Character Recognition):全称光学字符识别,是一项技术,通过使用光学和图像处理技术,将图像中的文字转换为可编辑的文本。

Segmentation:在图像处理领域,分割是指将整个图像分解为多个子部分的过程,以便进行进一步的处理。

OCR Segmentation:是指在光学字符识别过程中,将包含文本的图像分解成多个小部分的操作。这旨在有效地识别图像中的文字,并将其从背景中分离出来,以便后续的OCR处理。通过分割,系统可以更准确地定位和识别每个字符,提高整体识别准确性。

读入图像

读入图像:

一旦获得了包含文本的数字图像,或者通过扫描仪将某些文档转换为数字图像进行存储,就可以迈入下一步,即预处理。在这个阶段,可以使用以下代码来读入图像,以便进行后续的处理。

import cv2# 读入图像
myImage = cv2.imread('12.png')# 显示图像
cv2.imshow('Text Image', myImage)
cv2.waitKey(0)

在这里插入图片描述

图像二值化

在开始分割文本图像之前,需要经过一系列预处理步骤,其中之一是图像的二值化。这个过程包括以下步骤:

灰度化: 首先,将输入图像转换为灰度图像。这一步的目的是简化图像,使系统能够更轻松地识别图像中的不同形状,同时去除颜色信息,从而减少处理的复杂性。这通常通过将图像中的每个像素的彩色信息转化为相应的灰度值来实现。

import cv2# 读入图像
myImage = cv2.imread('12.png')# 灰度化
grayImage = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)# 二值化
_, binaryImage = cv2.threshold(grayImage, 128, 255, cv2.THRESH_BINARY)# 显示图像
cv2.imshow('Binary Image', grayImage)
cv2.waitKey(0)

在这里插入图片描述

二值化: 一旦图像变为灰度图,接下来的关键步骤是将其二值化。这意味着将图像中的像素值转换为两个可能的值之一,通常是0和255。这样的二值图像使得文字与背景更为明显,为后续的字符切分和识别提供了更好的基础。

这个可以根据自己的修改,转换颜色。

_, binaryImage = cv2.threshold(grayImage, 128, 255, cv2.THRESH_BINARY)
import cv2
# 读入图像
myImage = cv2.imread('12.png')
# 灰度化
grayImage = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)
# 二值化
_, binaryImage = cv2.threshold(grayImage, 128, 255, cv2.THRESH_BINARY)
# 显示图像
cv2.imshow('Binary Image', binaryImage)
cv2.waitKey(0)

在这里插入图片描述

import cv2# 读入图像
myImage = cv2.imread('12.png')# 灰度化
grayImage = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(grayImage, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
# 形态学操作
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 18))
dilation = cv2.dilate(thresh, horizontal_kernel, iterations=1)# 显示图像
cv2.imshow('Dilated Image', thresh)
cv2.waitKey(0)

在这里插入图片描述

接着可以选择并使用多种算法从上述二值图像中提取信息,例如直方图均衡、傅立叶变换、形态学等。
形态学操作

import cv2# 读入图像
myImage = cv2.imread('12.png')# 灰度化
grayImage = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(grayImage, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
# 形态学操作
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 18))
dilation = cv2.dilate(thresh, horizontal_kernel, iterations=1)# 显示图像
cv2.imshow('Dilated Image', dilation)
cv2.waitKey(0)

在这里插入图片描述

查找轮廓
接着需要找到轮廓线,这样才能将图像与背景逐行分离。
为了清楚,换红色线条标注,可以修改这段代码更换颜色

    rect = cv2.rectangle(myImage, (x, y), (x + w, y + h), (0, 0, 255), 1)  # 红色矩形
import cv2# 读入图像
myImage = cv2.imread('12.png')# 灰度化
grayImage = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(grayImage, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)# 形态学操作
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 18))
dilation = cv2.dilate(thresh, horizontal_kernel, iterations=1)# 查找轮廓
horizontal_contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)# 在原始图像上绘制红色矩形
for cnt in horizontal_contours:x, y, w, h = cv2.boundingRect(cnt)rect = cv2.rectangle(myImage, (x, y), (x + w, y + h), (0, 0, 255), 1)  # 红色矩形# 显示图像
cv2.imshow('Image with Red Rectangles', myImage)
cv2.waitKey(0)

在这里插入图片描述
单词和字符分割

接着我们通过以下步骤对裁剪出的轮廓子图进行单词分割:

1-预处理(灰度、阈值)

2-形态学算法

3-找到边界并绘制它们

4-进入单个字符分割

进而我们将对输出图像中的每个单词再次重复相同的步骤进行单个字符的分割:

1-预处理(灰度、阈值)

2-形态学算法

3-找到边界并绘制它们

4-停止

最终我们得到的结果如下。
代码:

import cv2# 读入图像
myImage = cv2.imread('12.png')# 灰度化
grayImage = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(grayImage, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)# 形态学操作
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 18))
dilation = cv2.dilate(thresh, horizontal_kernel, iterations=1)# 查找轮廓
horizontal_contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)# 在原始图像上绘制红色矩形和进行字符分割
for cnt in horizontal_contours:x, y, w, h = cv2.boundingRect(cnt)# 绘制红色矩形rect = cv2.rectangle(myImage, (x, y), (x + w, y + h), (0, 0, 255), 1)# 在水平轮廓区域内进行字符分割roi = thresh[y:y + h, x:x + w]# 进行字符分割的额外步骤,例如形态学操作、查找字符轮廓等char_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))char_dilation = cv2.dilate(roi, char_kernel, iterations=1)char_contours, _ = cv2.findContours(char_dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 在原始图像上绘制字符的边界for char_cnt in char_contours:char_x, char_y, char_w, char_h = cv2.boundingRect(char_cnt)char_rect = cv2.rectangle(myImage, (x + char_x, y + char_y), (x + char_x + char_w, y + char_y + char_h),(0, 255, 0), 1)# 显示图像
cv2.imshow('Image with Red Rectangles and Character Boundaries', myImage)
cv2.waitKey(0)

`
在这里插入图片描述

小结

在传统图像处理中,如何利用常见的形态学方法进行字符轮廓查找,从而实现字符的切分。通过提供相应的代码实现,展示了在一些字符分布简单、字符间隔较大的场景下,该方法能够取得一定的效果。然而,由于采用传统方案,该方法的泛化性较为有限。在面对更复杂的场景时,可以考虑借助神经网络等先进技术,以实现更加鲁棒和适用于多种情况的字符切分算法。

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

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

相关文章

Tomcat web.xml文件中的mime-mapping

在Tomcat安装目录的conf/web.xml文件中&#xff0c;定义了大量的<mime-mapping>元素&#xff0c;例如&#xff1a; 其中<extension>指定了文件的扩展名&#xff0c;<mime-type>指定了mime类型&#xff0c;放在<mime-mapping>元素中&#xff0c;就是将…

Spring Boot使用EhCache完成一个缓存集群

在上一篇在SpringBoot中使用EhCache缓存&#xff0c;我们完成了在Spring Boot中完成了对EhCaChe的使用&#xff0c;这篇&#xff0c;我们将对EhCache的进一步了解&#xff0c;也就是搭建一个EhCache的缓存集群。 集群 在搭建一个EhCache的时候&#xff0c;我们需要先了解&…

qt笔记之qml和C++的交互系列(一):初记

code review! —— 杭州 2023-11-16 夜 文章目录 一.qt笔记之qml和C的交互&#xff1a;官方文档阅读理解0.《Overview - QML and C Integration》中给出五种QML与C集成的方法1.Q_PROPERTY&#xff1a;将C类的成员变量暴露给QML2.Q_INVOKABLE()或public slots&#xff1a;将C类…

【python】均值、中值和高斯滤波详解和示例

本文对均值、中值和高斯滤波进行详解&#xff0c;以帮助大家理解和使用。 这里写目录标题 均值滤波中值滤波高斯滤波核大小为&#xff08;9,9&#xff09;核大小为&#xff08;51,51&#xff09; 小结 下面是示例中使用的原图。 均值滤波 均值滤波是一种简单的平滑滤波器&…

nodejs+vue教室管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

用户 用户管理&#xff1a;查看&#xff0c;修改自己的个人信息 教室预约&#xff1a;可以预约今天明天的教室&#xff0c;按着时间段预约&#xff08;可多选&#xff09;&#xff0c;如果当前时间超过预约时间段不能预约该时间段的教室 预约教室的时候要有个预约用途&#xff…

python趣味编程-5分钟实现一个Flappy Bird游戏(含源码、步骤讲解)

Python 中的 Flappy Bird 游戏可以免费下载开源代码,它是为想要学习 Python 的初学者创建的。 该项目系统使用了 Pygame 和 Random 模块。 Pygame 是一组跨平台的 Python 模块,专为编写视频游戏而设计。 Python 中的 Flappy Bird 代码 – 项目信息 项目名称:Python 中的 Fl…

redis设置密码

首先到redis的下载目录下&#xff1a;运行 redis-cli 查看redis密码&#xff1a; config get requirepass 设置redis密码为123456&#xff1a; config set requirepass 123456

Spring SPI

SPI 服务供给接口&#xff08;Service Provider Interface&#xff09;。是Java 1.5新添加的一个内置标准&#xff0c;允许不同的开发者去实现某个特定的服务。 1 SPI 介绍 一个接口&#xff0c;可能会有许多个实现&#xff0c;我们在编写代码时希望能动态切换具体实现&#…

基于STM32的循迹小车项目实战

循迹小车是一种能够沿着预定路线行驶的智能小车&#xff0c;通过巡线传感器检测路面的线路&#xff0c;并根据检测结果调整行驶方向。本项目将基于STM32微控制器实现一个简单的循迹小车&#xff0c;通过学习和实践&#xff0c;帮助初学者熟悉STM32的开发流程和掌握循迹小车的实…

linux运行java程序

这个帖子实现的是linux上运行java代码 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 事情发生的原因是博洋需要知道海外城市的数量&#xff0c;我一开始准备将全量数据拉取到本地&#xff0c;用代码遍历一遍。但是打包好全量数据&…

CentOS中安装常用环境

一、CentOS安装 redis ①&#xff1a;更新yum sudo yum update②&#xff1a;安装 EPEL 存储库 Redis 通常位于 EPEL 存储库中。运行以下命令安装 EPEL 存储库 sudo yum install epel-release③&#xff1a;安装 Redis sudo yum install redis④&#xff1a;启动 Redis 服…

MYSQL中的触发器TRIGGER

1.概念 触发器是一个特殊的存储过程&#xff0c;当触发器保护的数据发生变更时就会触发。 2.特性 1.触发器与表息息相关&#xff0c;一般我们一个表创建六个触发器。 2.六个触发器其实是三种类六个 insert 类型 before | after insertupdate 类型 before | af…

STM32中断看这一篇就够了

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 1. 前言…

基于SSM的教学管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【Proteus仿真】【Arduino单片机】HC05蓝牙通信

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、HC05蓝牙传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示蓝牙接收数据。 二、软件设计 /* 作者…

MR外包团队:MR、XR混合现实技术应用于游戏、培训,心理咨询、教育成为一种创新的各行业MR、XR形式!

随着VR、AR、XR、MR混合现实等技术逐渐应用于游戏开发、心理咨询、培训、教育各个领域&#xff0c;为教育、培训、心理咨询等行业带来了全新的可能性。MR、XR游戏开发、心理咨询是利用虚拟现实技术模拟真实场景&#xff0c;让学生身临其境地参与学习和体验&#xff0c;从而提高…

MapApp 地图应用

1. 简述 1.1 重点 1&#xff09;更好地理解 MVVM 架构 2&#xff09;更轻松地使用 SwiftUI 框架、对齐、动画和转换 1.2 资源下载地址: Swiftful-Thinking:https://www.swiftful-thinking.com/downloads 1.3 项目结构图: 1.4 图片、颜色资源文件图: 1.5 启动图片配置图: 2. Mo…

Linux | 安装openGauss数据库

Linux 安装openGauss数据库 今天我们来安装一下国产数据库openGauss~~ 下载openGauss 首先在官网:https://opengauss.org/zh/download/下载对应的安装包&#xff0c;我们这里下载LInux 极简版来演示安装 下载后,使用root用户上传到Linux ,这边上传到/usr/local/目录下, 使用…

IoC和DI

Spring 是包含众多工具的 IoC 容器,存的是对象,对象这个词在 Spring 的范围内,称之为 bean IoC 是控制反转 控制权进行了反转,比如对某一个东西的控制权在 A 手上,结果变成了 B ,Spring 管理的是 bean ,所以这里的控制权指的是 bean 的控制权,也就是对象的控制权进行了反转 …

SAP PI/PO中使用UDF解决按字节拆分字符串的需求

需求背景&#xff1a; SAP需要将采购订单信息通过PI发送到SFTP服务器上&#xff0c;生成文件&#xff0c;一般对日项目上文件内容通常都是按照指定的字节数拆分的&#xff0c;而不是字符数&#xff0c;类似下面的格式。 问题点&#xff1a; 如果是使用FTP适配器&#xff0c;则…