有时候文本是倾斜的,则不利于文本识别,如下图所示,那么进行文本识别之前我们需要应用文本倾斜校正算法(text skew correction,deskewing text)。

对于一幅包含旋转文本块的图像,我们需要通过以下方式纠正文本倾斜:检测图像中的文本块

确定文本块的倾斜角度和倾斜方向

旋转图像以校正倾斜的文本

那么我们开始吧。

首先读取图像并转换为灰度图:

img_path = "text.jpg"

img = cv2.imread(img_path)

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

在进行图像处理操作时,前景通常为亮色,而背景(图像中不感兴趣的部分)通常是暗的。但是我们的输入图像是白底黑字,所以需要反转图像,让文本部分作为前景。

# flip the foreground and background to ensure text is "white"

gray = cv2.bitwise_not(gray)

先进行高斯模糊,再对图像进行阈值处理得到二值图像:

blur = cv2.GaussianBlur(gray, (7,7), 0)

# setting all foreground pixels to 255 and all background pixels to 0

ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

如下图所示:

对于这个二值图像,我们先获取图像中灰度值不为零的所有像素的坐标(x,y),这些都是表示文本的像素。

whereid = np.where(thresh > 0)

# 交换横纵坐标的顺序,否则下面得到的每个像素点为(y,x)

whereid = whereid[::-1]

# 将像素点格式转换为(n_coords, 2),每个点表示为(x,y)

coords = np.column_stack(whereid)

np.where 的用法可以查看 这里,对于二维图像,whereid 是一个包含两个元素的列表,第一个元素为所有满足要求的像素的纵坐标,第二个元素为所有满足要求的像素的横坐标。

我们需要使用 whereid[::-1] 交换横纵坐标的顺序,下一步,使用 np.column_stack 将所有像素点坐标转换为 (n_pixel, 2),其中每个像素点坐标表示为 (x, y)。np.column_stack 的用法可以查看 这里。

我们就可以根据这些像素坐标来计算文本倾斜的角度和方向。

(x,y), (w,h), angle = cv2.minAreaRect(coords)

if angle < -45:

angle = 90 + angle

通过 cv2.minAreaRect(coords) 来得到包含整个文本区域的最小旋转矩形,cv2.minAreaRect(coords) 的用法可以查看我的这篇文章 OpenCV 中的轮廓应用。

会得到这个区域的倾斜角度angle,angle的范围为 (-90,-0],一个正矩形框逆时针旋转,

的值变化为:-0 -> -30 -> -60 -> -0,然后不断循环。

所以这个角度值就是逆时针旋转的角度,当旋转角度小于-45度时,我们需要加上90度,具体原因后面解释。

为了更好地理解我们得到的是一个什么矩形框,这里额外添加一步绘图操作:

vis = img.copy()

box = cv2.boxPoints(((x,y), (w,h), angle))

box = np.int0(box)

cv2.drawContours(vis,[box],0,(0,0,255),2)

这几句具体代表什么意思,可以查看这篇文章 OpenCV 中的轮廓应用,这不是本文重点,就不多说了。

终于来到最后一步了,对倾斜文本进行校正。

# rotate the image to deskew it

h, w = image.shape[:2]

center = (w // 2, h // 2)

# center = x, y # 可以试试中心点设置为文本区域中心会是什么情况

Mat = cv2.getRotationMatrix2D(center, angle, 1.0)

rotated = cv2.warpAffine(image, Mat, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)

我们先得到整个图像的中心点center,这里通过 cv2.warpAffine 进行对图像进行仿射变换来实现校正倾斜文本。

仿射变换对角度要求是:angle为正,则逆时针选择;angle为负,则顺时针旋转。当文本倾斜角度范围为 (-45, 0) 时,即小于45度的负角度,表示文本逆时针倾斜,该角度不进行处理,在仿射变换时顺时针旋转。

当文本倾斜角度范围为 (-90, -45) 时,表示文本顺时针倾斜,对该角度加上90度,得到一个小于45度的正角度,在仿射变换时逆时针旋转。

关于仿射变换的详细信息可以查看这篇文章 图像的仿射变换。

通过 cv2.getRotationMatrix2D 得到旋转矩阵,根据旋转矩阵,那么就可以使用 cv2.warpAffine 来对图像进行仿射变换,从而实现文本倾斜校正。

使用如下语句在旋转后的图上绘制出倾斜的角度:

cv2.putText(rotated, "Angle: {:.2f} degrees".format(angle), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

最终的结果图为:

该图的倾斜角度为 -3.87,即逆时针倾斜3.87度,校正后的效果还是比较好的。

看一下更多的例子:

参考:OpenCV - Rotation (Deskewing)​felix.abecassis.meText skew correction with OpenCV and Python - PyImageSearch​www.pyimagesearch.com

如果觉得有用,点个赞吧(ง •̀_•́)ง。

python图像倾斜校正_校正倾斜的文本相关推荐

  1. python图像隐写_在图像中隐藏数据:用 Python 来完成图像隐写术

    什么叫"隐写术"? 隐写术是将保密信息掩藏在更大的信息内容中,使他人没法了解掩藏信息内容的存有及其掩藏信息的全过程.隐写术的目地是确保彼此中间的商业秘密沟通交流.与掩藏保密信息內容 ...

  2. python 文字识别 准确率_关于OCR图片文本检测、推荐一个 基于深度学习的Python 库!...

    大家好,我是 zeroing~ 1,前言 之前谈到图片文本 OCR 识别时,写过一篇文章介绍了一个 Python 包 pytesseract ,具体内容可参考 介绍一个Python 包 ,几行代码可实 ...

  3. python图像去污_图像去雾----暗通道

    暗通道去雾算法原理及实现 1. 算法原理. 暗通道. 所谓暗通道是一个基本假设,这个假设认为,在绝大多数的非天空的局部区域中,某一些像素总会有至少一个颜色通道具有很低的值.这个其实很容易理解,实际生活 ...

  4. python图像下采样_图像的上采样(upsampling)与下采样(subsampled)

    缩小图像(或称为下采样(subsampled)或降采样(downsampled))的主要目的有两个:1.使得图像符合显示区域的大小:2.生成对应图像的缩略图. 放大图像(或称为上采样(upsampli ...

  5. python图像开闭区间_自动开闭器不良故障案例分析

    问题:怎样才能每天收到这种文章? 答案:点击上方蓝色字体,再点击关注即可! 一.故障概况 某年10月26日13:00分,某站的16/18号道岔在排列进路时,从定位操纵到反位时,反位无表示. 二.监测数 ...

  6. Python 图像 一样大小_#带你学Python# 表白利器:用Python发微信表情画-带你认识图片的秘密...

    首先感谢大家对上篇文章"python实现传染病模型"的肯定: 孙小白:#带你学Python# 疫情当前,在家没事?你也可以用Python预测疫情发展​zhuanlan.zhihu. ...

  7. python图像融合算法_图像融合质量评价方法的python代码实现——MS-SSIM

    图像融合质量评价方法的python代码实现--MS-SSIM 图像融合质量评价方法的python代码实现--MS-SSIM 文章目录 1 前言 2 MS-SSIM介绍 2 MS-SSIM的代码 2.1 ...

  8. Python 图像 一样大小_媲美 PS,用 Python 制作酷炫极坐标全景图

    点击上方"Python数据之道",选择"星标公众号" 收藏文章的同时,不要忘记「在看」 媲美 PS, 用 Python 制作酷炫极坐标全景图 0 概述  今天要 ...

  9. python图像纹理提取_提取图像的颜色、纹理特征(传统算法)

    Python-Image-feature-extraction Python实现提取图像的纹理.颜色特征,包含快速灰度共现矩阵(GLCM).LBP特征.颜色矩.颜色直方图.1044197988/Pyt ...

最新文章

  1. 正确实现用spring扫描自定义的annotation
  2. python anova_anova_lm()python:它适用于哪种模型类型?
  3. 2006第三季度:10大最糟科技事件
  4. ROS和OpenCV的对接cv_bridge
  5. Orleans入门例子
  6. 多核 linux 绑定,Linux 操作系统下CPU多核心的绑定
  7. [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店...
  8. 证明task线程是来源于线程池的,线程重用
  9. 【文章收藏】阿里云破了四个世界纪录
  10. 神经网络技巧篇之寻找最优参数的方法
  11. Java中构造函数,静态代码块,构造代码块的执行顺序
  12. 怎样查看本机到一个网站经过多少路由节点?
  13. CentOS6/CentOS7系统配置IPv6地址的方法
  14. 桌面壁纸被计算机管理员禁用,Win7更改桌面壁纸时出现“此功能已被禁用”如何解决...
  15. 管理信息系统开发方法——原型法
  16. 搜索与问答——【NeurIPS 2021】BEIR:信息检索模型零样本评估的异构基准
  17. dig 域名信息查询
  18. 5 降维 Dimention Reduction
  19. Python抓取淘女郎网页信息以及代码下载
  20. 基于ZKEACMS的.Net Core多租户CMS建站系统

热门文章

  1. 【必会】SQL 命令大全
  2. 深度增强学习:走向通用人工智能之路
  3. 计算机上的放大快捷键,电脑放大镜热键 怎么取消电脑放大镜快捷键?
  4. linux下qt打印功能如何实现,Qt Graphics-View的打印功能实现
  5. iOS视频编辑SDK
  6. 常犇_专访丨《河神》制片人常犇:走夜路不怕黑,做好剧别怕累
  7. Shell脚本——条件语句
  8. Android Bmob
  9. 对人工智能芯片的一些看法
  10. 用matlab画树叶,matlab画漂亮的树叶