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

news2024/11/28 0:46:24

文章目录

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

概要

在处理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.coloradmin.cn/o/1216391.html

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

相关文章

AI中文版怎么用,版本分享,GPT官网入口

网页版上线啦,在线助力大学生、上班族的高效生活! GPT4.0是OpenAI最新推出的聊天模型,它的语言理解和生成能力比以前的版本更强大。对于忙碌的上班族来说,GPT4.0能帮助你高效处理工作中的大部分写作任务,比如撰写报告…

TS7031: Binding element ‘role‘ implicitly has an ‘any‘ type.

文章 前言错误场景问题分析解决方案后言 前言 ✨✨ 他们是天生勇敢的开发者,我们创造bug,传播bug,毫不留情地消灭bug,在这个过程中我们创造了很多bug以供娱乐。 前端bug这里是博主总结的一些前端的bug以及解决方案,感兴…

【C++】类和对象(5)--拷贝构造函数

目录 一 概念 二 拷贝构造函数特性 1. 重载形式 2. 参数原则 3 默认拷贝函数 三 拷贝构造函数的实现 一 概念 在创建对象时,可否创建一个与已存在对象一某一样的新对象呢? class Date { public:Date(int year 1900, int month 1, int day 1)/…

nestJs 高阶用法

真正的服务器需要做全局的数据核查、敏感操作落库和数据转化。 拥有这些能力才能让后台能力更加丰富,本篇将主要使用 NestJs 的高级能力,来实现这些功能。 使用 guards 和 decorators 实现数据校验核查通过 interceptors 和 decorators 实现敏感操作录…

Linux三剑客:grep的基本使用

目录 grep介绍 什么是grep和egrep 使用grep 命令格式 命令功能 命令参数 grep配合正则表达式使用 认识正则 基本正则表达式 匹配字符 配置次数 位置锚定:定位出现的位置 分组和后向引用 作为学习一名计算机专业的学生,我想Linux应该需要了解…

详细自动化测试介绍

📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试」资…

【10套模拟】【5】

关键字: 数据的最小单位、归并排序(两两归并)、单链表顺序存取、邻接表表头顶点顺序存储随机访问、三角矩阵元素个数、堆的性质、冒泡排序、二叉树是否相同

我对需求分析的理解

一、背景 最近做了一个项目,也算是踩坑过程,产品上线了,用户不怎么买单,使用者聊聊无几,前期一直不清楚为什么会这样,诚然新系统的开发设计上采用了更新的技术,设计上采用了更好的理念&#xf…

知识梳理到了领域榜一,意外,开心。

我的护城河 就是掌握的不断更新的技术。 一直被认可的能力。 完美的项目交付。 写的文章得到了读者们的认可。 希望我做的努力被更多的人看到。 分享的代码片可以解决他人的问题。 很惊喜,今早我的文章被数据结构和算法领域内容榜排到了第一名。 被认可的感觉很棒。…

Python-pptx教程之二操作已有PPT模板文件

文章目录 简单的案例找到要修改的元素修改幻灯片中的文本代码使用示例 修改幻灯片的图片代码使用示例 删除幻灯片代码使用示例 获取PPT中所有的文本内容获取PPT中所有的图片总结 在上一篇中我们已经学会了如何从零开始生成PPT文件,从零开始生成较为复杂的PPT是非常消…

【重点文章】服务升级惨痛教训

文章目录 事故解析:避免方法涉及知识 以前怎么接触过大表,所以alter操作我都是一次性执行好几条的,这几条一下子干过去了   结果就是一直在转圈执行,因为alter产生的是表级排它锁,所以有关这几个表的查询更新操作全部处于阻塞…

04-学成在线之系统管理服务模块之查询数据字典表中的内容,前后端联调测试

前后端联调 配置前端环境 实际开发中先由后端工程师将接口设计好并编写接口文档并交给前端工程师,前后端的工程师就开始并行开发 前端开发人员先自己mock数据即使用假数据进行开发,当后端代码完成后前端工程师尝试请求后端接口获取数据然后渲染到页面 第一步: 首…

大力说企微第一课:企业微信的注册验证和认证

这段时间有好几个朋友问我,怎么用企业微信,还有一些朋友反馈,企业微信使用起来不太方便。 在我的印象中,企业微信确实不如微信那么简单,毕竟用户对象是企业,是企业就有多个部门,就有流程&#x…

ubuntu20源码编译搭建SRS流媒体服务器

第一、下载源码 下载源码,推荐用Ubuntu20: git clone -b develop https://gitee.com/ossrs/srs.git第二、编译 2.1、切换到srs/trunk目录: cd srs/trunk2.2、执行configure脚本 ./configure2.3、执行make命令 make2.4、修改conf/rtmp.c…

零代码实现问卷网与巨量引擎的对接

通过数环通,您可以使用不到几分钟的时间即可实现问卷网与巨量引擎的对接与集成,从而高效实现工作流程自动化,降本增效! 1.产品介绍 巨量引擎是字节跳动旗下的营销服务品牌,它整合了字节跳动旗下的产品及海量内容&…

简单高效的定制移动固态硬盘,稳定易用的办公小助手

我在平时的工作中,常常需要处理各种大文件和数据,如果硬盘速度跟不上,那工作效率就会大幅降低。今年固态硬盘的价格大幅下降,有很多国产品牌加入其中,很容易找到一款性价比高的固态硬盘,搭配硬盘盒使用&…

mac清除所有数据,不抹除的情况下如何实现?

mac清除所有数据是一个比较复杂的任务,尤其是在不进行系统抹除的情况下。但是,如果你想要将mac完全恢复到出厂设置的状态,同时保留数据,本文将介绍一些可行的方法,帮助您在不抹除硬盘数据的情况下,让mac清除…

Ganache结合内网穿透实现远程不同局域网公网访问

文章目录 前言1. 安装Ganache2. 安装cpolar3. 创建公网地址4. 公网访问连接5. 固定公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默,忍不住分享一下给大家。 点击跳转到网站…

Zookeeper Java 开发,自定义分布式锁示例

文章目录 一、概述二、导入依赖包三、创建锁的过程3.1 通过 create 创建节点信息3.2 AsyncCallback.StringCallback 回调函数3.3 AsyncCallback.Children2Callback 的回调函数3.4 Watcher 的回调函数 四、完整示例4.1 完整分布式锁代码4.2 测试类 如果您还没有安装Zookeeper请看…

Shopee选品工具软件——知虾,助您轻松把握市场趋势

在如今竞争激烈的电商市场中,了解市场趋势和数据分析是成功的关键。对于Shopee虾皮平台上的商家来说,知虾是一款强大的选品工具软件,它提供了全面的数据分析服务,帮助商家快速了解大盘走势,并挖掘潜力行业类目。本文将…