点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

今天,我们想与您分享解决图像偏移校正问题(拉直旋转图像)的简单解决方案。如果我们正在从歪斜图像中提取文本的内容,则必须以一种或另一种形式处理图像。从摄像机图片到扫描的文档-将清理后的图像馈送到OCR工具之前,去歪斜是图像预处理中的必要步骤。

去歪斜算法

让我们开始讨论Deskeweing算法的一般概念。我们的主要目标是将旋转的图像分成文本块,并确定它们的角度。为了让您详细了解我将使用的方法:

1. 照常-将图像转换为灰度。

2. 应用轻微的模糊以减少图像中的噪点。

3. 现在,我们的目标是找到带有文本的区域,即图像的文本块。为了使文本块检测更容易,我们将反转并最大化图像的颜色,这将通过阈值化来实现。因此,现在文本变为白色(恰好为255,255,255白色),而背景为黑色(同样为0,0,0黑色)。

4. 要查找文本块,我们需要合并该块的所有打印字符。我们通过膨胀(扩展白色像素)来实现。在X轴上使用较大的内核可以消除单词之间的所有空间,而在Y轴上使用较小的内核可以将彼此之间的一个块的行混合在一起,但保持文本块之间的较大间隔不变。

5. 现在,用最小面积矩形包围轮廓的简单轮廓检测将形成我们需要的所有文本块。

6. 确定倾斜角度的方法有很多种,但我们将坚持简单的方法-使用最大的文本块并使用其角度。

现在切换到python代码:

# Calculate skew angle of an image
def getSkewAngle(cvImage) -> float:#Prep image, copy, convert to gray scale, blur, and thresholdnewImage = cvImage.copy()gray = cv2.cvtColor(newImage, cv2.COLOR_BGR2GRAY)blur = cv2.GaussianBlur(gray, (9, 9), 0)thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV +cv2.THRESH_OTSU)[1]#Apply dilate to merge text into meaningful lines/paragraphs.#Use larger kernel on X axis to merge characters into single line, cancellingout any spaces.#But use smaller kernel on Y axis to separate between different blocks of textkernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 5))dilate = cv2.dilate(thresh, kernel, iterations=5)#Find all contourscontours, hierarchy = cv2.findContours(dilate, cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)contours = sorted(contours, key = cv2.contourArea, reverse = True)#Find largest contour and surround in min area boxlargestContour = contours[0]minAreaRect= cv2.minAreaRect(largestContour)#Determine the angle. Convert it to the value that was originally used to obtainskewed imageangle = minAreaRect[-1]if angle < -45:angle = 90 + anglereturn -1.0 * angle

获得偏斜角后,我们只需要重新旋转图像即可:

# Rotate the image around its center
def rotateImage(cvImage, angle: float):newImage = cvImage.copy()(h, w) = newImage.shape[:2]center = (w // 2, h // 2)M= cv2.getRotationMatrix2D(center, angle, 1.0)newImage = cv2.warpAffine(newImage, M, (w, h), flags=cv2.INTER_CUBIC,borderMode=cv2.BORDER_REPLICATE)return newImage# Deskew image
def deskew(cvImage):angle = getSkewAngle(cvImage)return rotateImage(cvImage, -1.0 * angle)

可视化步骤

可视化步骤

关于角度计算的注释

其他案例可能需要更多的计算,而不仅仅是采取最大的方法,并且可以开始尝试一些其他策略。

1-   可以使用所有文本块的平均角度:

allContourAngles = [cv2.minAreaRect(c)[-1]for c in contours]
angle = sum(allContourAngles) /len(allContourAngles)

2-   可以采用中间块的角度:

middleContour = contours[len(contours) //2]
angle = cv2.minAreaRect(middleContour)[-1]

3-   可以尝试最大,最小和中间块的平均角度。

largestContour = contours[0]
middleContour = contours[len(contours) //2]
smallestContour = contours[-1]
angle =sum([cv2.minAreaRect(largestContour)[-1], cv2.minAreaRect(middleContour)[-1],cv2.minAreaRect(smallestContour)[-1]]) / 3

那只是我们可以立即想到的一些替代方式。继续尝试,找出最适合您的情况的方法!

测验

为了测试这种方法,我使用了一个新生成的带有Lorem Ipsum文本的PDF文件。本文档的首页以300 DPI分辨率(使用PDF文档时最常用的设置)呈现。之后,通过拍摄原始图像并在-10度到+10度范围内随机旋转来生成20个样本图像的测试数据集。然后,我将图像及其倾斜角度保存在一起。您可以在我的GitHub存储库中找到用于生成这些示例图像的所有代码,这里不再赘述。

测试结果的统计样本:

Item #0,with angle=1.77, calculated=1.77, difference=0.0%
Item #1,with angle=-1.2, calculated=-1.19, difference=0.83%
Item #2,with angle=8.92, calculated=8.92, difference=0.0%
Item #3,with angle=8.68, calculated=8.68, difference=0.0%
Item #4,with angle=4.83, calculated=4.82, difference=0.21%
Item #5,with angle=4.41, calculated=4.4, difference=0.23%
Item #6,with angle=-5.93, calculated=-5.91, difference=0.34%
Item #7,with angle=-3.32, calculated=-3.33, difference=0.3%
Item #8,with angle=6.53, calculated=6.54, difference=0.15%
Item #9,with angle=-2.66, calculated=-2.65, difference=0.38%
Item #10,with angle=-2.2, calculated=-2.19, difference=0.45%
Item #11,with angle=-1.42, calculated=-1.4, difference=1.41%
Item #12,with angle=-6.77, calculated=-6.77, difference=0.0%
Item #13,with angle=-9.26, calculated=-9.25, difference=0.11%
Item #14,with angle=4.36, calculated=4.35, difference=0.23%
Item #15,with angle=5.49, calculated=5.48, difference=0.18%
Item #16,with angle=-4.54, calculated=-4.55, difference=0.22%
Item #17,with angle=-2.54, calculated=-2.54, difference=0.0%
Item #18,with angle=4.65, calculated=4.66, difference=0.22%
Item #19,with angle=-4.33, calculated=-4.32, difference=0.23%
MinError: 0.0%
MaxError: 1.41%
Avg Error: 0.27%

这种方法效果很好,与真实的歪斜角度仅产生很小的偏差。对于人眼和OCR引擎而言,此类错误已不再明显。

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

如何使用OpenCV自动校正文本图像相关推荐

  1. opencv倾斜校正 java,OpenCV实现基于傅里叶变换的旋转文本校正

    代码 先给出代码,再详细解释一下过程: #include #include #include #include using namespace cv; using namespace std; #de ...

  2. opencv离散傅里叶变换进行图像旋转校正

    前言 离散傅立叶变换的一个应用是决定图片中物体的几何方向.     观察这两张幅度图你会发现频域的主要内容(幅度图中的亮点)是和空间图像中物体的几何方向相关的. 通过这点我们可以计算旋转角度并修正偏差 ...

  3. 在OpenCV环境下对图像做Gamma校正

    什么是Gamma校正? Gamma校正是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系. 上面中的指数γ即为Gamma. 经过Gamma校正后的输入和输出图像灰度值关系如 ...

  4. html 输入框并行,Python:输入文本框并行捕获userinput到OpenCV Live网络摄像头图像...

    我有一个简单的脚本运行流式传输我的网络摄像头的图像,我想做一些像canny-filter和hough转换一样的操作来检测liveimage中的行:Python:输入文本框并行捕获userinput到O ...

  5. 基于OpenCV的表格文本内容提取

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 小伙伴们可能会觉得从图像中提取文本是一件很麻烦的事情,尤其是需要提 ...

  6. 利用OpenCV实现旋转文本图像矫正的原理及OpenCV代码

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 对图像进行旋转矫正,关键是要获取旋转角度是多少! ...

  7. OpenCV 相机校正

    1. 相机标定 根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和畸变系数. 标定的流程是: 准备棋盘格数据,即用于标定的图片 对每一张图片提取角点信息 在棋盘上绘制 ...

  8. 智慧交通day03-车道线检测实现03:相机校正和图像校正的实现

    1.相机标定 根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和畸变系数. 标定的流程是: 准备棋盘格数据,即用于标定的图片 对每一张图片提取角点信息 在棋盘上绘制提 ...

  9. youcans 的 OpenCV 学习课—4.图像的叠加与混合

    youcans 的 OpenCV 学习课-4.图像的叠加与混合 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 本节介绍图像的加法.叠加与混合,提供完整例程和运行结果:加法 ...

最新文章

  1. 20172304 《程序设计与数据结构》第九周学习总结
  2. 【深度学习】ICCV2021|性能优于何恺明团队MoCo v2,DetCo:为目标检测定制任务的对比学习...
  3. Java不同压缩算法的性能比较
  4. 关于猿如何找对象,心里没点那啥数吗?
  5. uniapp使用iconfont字体图标
  6. SQL Server 日期函数:EOMonth、DateFormat、Format、DatePart、DateName
  7. Python 源码剖析(二)—— 第一次修改 Python 源代码
  8. POJ 1026 Cipher
  9. js中的onscroll的用法
  10. MySQL INFORMATION_SCHEMA信息数据库
  11. oracle中插入图片,在Oracle数据库的表中插入图片的方法
  12. 高费率基金是投资者的毒药
  13. 计算机主机运行显示屏黑屏,电脑开机黑屏_电脑启动显示器黑屏的原因和检修-太平洋IT百科...
  14. [转帖]妇联4剧透 看不起电影看剧透.
  15. 辗转相除法求最大公因数
  16. 2017-2018-2 20155225《网络对抗技术》实验四 恶意代码分析
  17. python进行批量图片文字识别
  18. 运维宝典:常用运维命令合集服务器配置、防火墙配置
  19. 计算机职业生涯规划书图文并茂,计算机职业生涯规划书范文
  20. 什么是JavaBean?什么是Bean?

热门文章

  1. 受用一生的高效PyCharm使用技巧
  2. 程序员入错行怎么办?
  3. Google、Facebook、亚马逊、Uber等硅谷顶尖AI专家团北京聚首 ,这场AI开发者盛会不可错过
  4. 中国首场AI芯片产业峰会成功举办 GTIC 2018热度空前
  5. 干掉visio,这个画图神器真的绝了!!!
  6. 代码规范+设计模式落地之路
  7. 2021 年技术 5 大趋势
  8. 不要再满屏写 try...catch 了!这个更香!
  9. 点赞模块设计:Redis缓存 + 定时写入数据库实现高性能点赞功能
  10. Java 如何设计 API 接口,实现统一格式返回?