opencv获取模板旋转角度_OpenCV入门之获取图像的旋转角度

在我们的日常生活中,所碰到的图像往往都有一定的倾斜。那么,如何用OpenCV来获取图像的旋转角度呢?   我们以下面的图片为例,简单介绍如何用OpenCV来获取图像的旋转角度。

f8c870f285b0d4ed7e990e0c84484f45.png

可以看到,该图像存在着许多噪声,且是彩色图片,因此,需要对图像做预处理。

预处理

图像的预处理包括去除边缘,去除噪声(两条灰色线),滤波,二值化等,具体处理的Python代码如下:

# -*- coding: utf-8 -*-

import cv2

imagepath = 'F://CHN_Char/4.png'

img = cv2.imread(imagepath, 1)

# 将图片的边缘变为白色

height, width = img.shape[0:2]

for i in range(width):

img[0, i] = [255]*3

img[height-1, i] = [255]*3

for j in range(height):

img[j, 0] = [255]*3

img[j, width-1] = [255]*3

# 去掉灰色线(即噪声)

for i in range(height):

for j in range(width):

if list(img[i,j]) == [204,213,204]:

img[i,j]=[255]*3

# 把图片转换为灰度模式

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

# 中值滤波

blur = cv2.medianBlur(gray, 3) # 模板大小3*3

# 二值化

ret,thresh = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)

# 保存图片

cv2.imwrite('F://CHN_Char/char_after_bin.png', thresh)

预处理后的图片如下:

50a10c8228e32939a5438cfb06fdf986.png

可以看到,预处理后的图像基本不含噪声,且是黑色图片,这样,我们就可以进行后续操作了。

获取旋转角度

对于上述预处理后的图片,可以用OpenCV的最小外接矩形方法(minAreaRect())来操作,该方法会返回最小外界矩形的中心点左边,矩形宽度、高度,以及旋转角度。因为图像中只有一个文字,因此包含该文字的最小外接矩形返回的角度就是图像的旋转角度(当然也有可能是负值)。   完整的Python代码如下:

# -*- coding: utf-8 -*-

import cv2

import numpy as np

imagepath = 'F://CHN_Char/char_after_bin.png'

img = cv2.imread(imagepath, -1)

image, contours, _ = cv2.findContours(img, 2, 2)

for cnt in contours:

# 最小外界矩形的宽度和高度

width, height = cv2.minAreaRect(cnt)[1]

if width* height > 100:

# 最小的外接矩形

rect = cv2.minAreaRect(cnt)

box = cv2.boxPoints(rect) # 获取最小外接矩形的4个顶点

box = np.int0(box)

if 0 not in box.ravel():

'''绘制最小外界矩形

for i in range(4):

cv2.line(image, tuple(box[i]), tuple(box[(i+1)%4]), 0) # 5

'''

# 旋转角度

theta = cv2.minAreaRect(cnt)[2]

if abs(theta) <= 45:

print('图片的旋转角度为%s.'%theta)

angle = theta

# 仿射变换,对图片旋转angle角度

h, w = img.shape

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

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

rotated = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)

# 保存旋转后的图片

cv2.imwrite('F://CHN_Char/after_rotated.png', rotated)

输出结果如下:

图片的旋转角度为-23.629377365112305.

得到的图像如下:

03590eda4558d1277658b5a68ef5acc0.png

在上述Python代码中,先是利用minAreaRect()获取图像中的最小外接矩形,加上一定的筛选条件(如矩形的面积大于100,旋转角度小于45度等)就能得到包含文字的最小外界矩形,其旋转角度就是整个图像的旋转角度。

识别图像中的文字

有了旋转后的图像,我们不妨利用Tesseract-OCR软件来识别图像中的文字,完整的Python代码如下:

import pytesseract

import cv2

# tesseract.exe所在的文件路径

pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)/Tesseract-OCR/tesseract.exe'

imagepath = 'F://CHN_Char/after_rotated.png'

image = cv2.imread(imagepath, -1)

text = pytesseract.image_to_string(image, lang='chi_sim', config='-psm 10')

print("Tesseract-OCR的识别结果为: '%s'."%text)

输出结果为:

Tesseract-OCR的识别结果为: '知'.

因此,我们得到的图像的旋转角度是正确的。当然,借用以上方法,还可以识别以下图片中的文字:

e860573f3838004e60d96bccdf23c540.png

总结

本次获取图像的旋转角度是利用了图像中只有一个文字,而包含该文字的最小外接矩形的旋转角度就是图像的旋转角度。这只是获取图像旋转角度的一种方式,当然,还会有其他获取图像旋转角度的方法,后续还会继续介绍,欢迎大家交流~~

注意:本人现已开通微信公众号: 轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

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

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

相关文章

后台使用orm多还是直接sql_Django应用app创建及ORM

Django应用app创建及ORM一.重要知识点回顾:1. form表单提交数据的注意事项&#xff1a;1. 是form不是from,必须要有method和action (action用来指定你的数据提交到后台哪个地方&#xff0c;method用来指定你提交数据的方式)2. 所有获取用户输入的表单标签要放在form表单里面&am…

java ruby脚本_Java 程序中直接执行 Ruby 脚本 (JRuby)

1.[代码]MainClass.javaimport java.io.BufferedReader;import java.io.FileReader;import javax.script.Invocable;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;public class MainClass {public static void main(String[] args) throws Excep…

python win32gui安装_python-无法安装win32gui

我正在尝试使用pip安装win32gui,但出现错误&#xff1a; C:\Users\?????>pip install win32gui Collecting win32gui Using cached https://files.pythonhosted.org/packages/b8/75/7bed82934e51903f9d48b26b3996161bb2dce1731607b4bb7fd26003ed3e/win32gui-221.5.tar.…

时间戳 java_java中获取时间戳的方法

在java开发过程中经常会遇到统计某一天或是某一个月的数据&#xff0c;因此常常需要获取截取数据的两个时间戳(比如统计今天的数据&#xff0c;则需要获取一个开始时间为今天零点以及一个结束时间为明天零点)&#xff0c;然后根据数据相关的时间是否在该时间区间内来判断是否将…

求一批整数中出现最多的个位数字_C语言经典100例007-求低n-1位的数

系列文章《C语言经典100例》持续创作中&#xff0c;欢迎大家的关注和支持。喜欢的同学记得点赞、转发、收藏哦&#xff5e;后续C语言经典100例将会以pdf和代码的形式发放到公众号欢迎关注&#xff1a;计算广告生态 即时查收1 题目函数&#xff1a;unsigned fun(unsigned w)功能…

python合并多个pdf_python合并多个pdf文件

假设您有个无聊的工作&#xff0c;将几十个PDF文档合并成一个PDF文件。 他们每个都有封面页作为第一页&#xff0c;但你不希望在最终结果中重复覆盖表。 即使有有很多免费的程序来组合PDF&#xff0c;其中许多只是合并整个文件在一起。 让我们编写一个Python程序来自定义哪些页…

python class类_python类class基础

44、class类&#xff1a;一、类定义的一般形式&#xff1a;1、简单的形式&#xff1a;实例化对象没有自己独有的数据属性。>>> class fistclass():... data1 hello world ### >这是类的数据属性或类成员属性。... def printdata(self): ###>这是类的方法&#…

java文件序列化_Java序列化与反序列化,文件操作

参考两篇博客&#xff1a;http://blog.csdn.net/moreevan/article/details/6697777http://blog.csdn.net/moreevan/article/details/6698529针对第二篇博客&#xff0c;看了下面的评论&#xff0c;发现子类输出的书号其实是父类的&#xff0c;书名是自己先添加的成员变量&#…

python 彻底解读多线程与多进程_python 多进程与多线程浅析

python多线程是伪多线程&#xff0c;同时间最多只有一个线程在执行&#xff0c;但这样并不代码python的多线程没有作用&#xff0c;对于IO密集型的系统&#xff0c;python的多线程还是能极大的提升性能&#xff5e;关于python伪多线程可以去了解python GIL的概念。以下代码涉及…

python什么软件开发好_python怎样才能学好?python软件开发什么

众所周知&#xff0c;Python是近年来热门的编程语言之一&#xff0c;吸引了很多人参与到it行业的Python开发中来&#xff0c;但是如何学习Python编程呢?对于每一个初学Python的朋友来说&#xff0c;估计有点困惑。那么我们如何才能学好Python呢?学习Python需要什么技能?有些…

java 设计模式原则_Java设计模式的七大原则

设计原则名称定 义使用频率单一职责原则(Single Responsibility Principle, SRP)一个类只负责一个功能领域中的相应职责。★★★★☆开闭原则(Open-Closed Principle, OCP)软件实体应对扩展开放&#xff0c;而对修改关闭。开闭原则的关键在于抽象化。★★★★★里氏代换原则(L…

python自定义模块和三方模块_python基础知识8——模块1——自定义模块和第三方开源模块...

模块的认识模块&#xff0c;用一砣代码实现了某个功能的代码集合。类似于函数式编程和面向过程编程&#xff0c;函数式编程则完成一个功能&#xff0c;其他代码用来调用即可&#xff0c;提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来&#xff0c;可能需要多个函数…

dhcp只能分配与路由器相同网段么_路由器的桥接详解

网上关于路由器无线桥接的教程很多&#xff0c;让你注意那注意这的&#xff0c;都没有说明白。今天&#xff0c;我来试着缕清它们间的关系&#xff01;1、主路由器这是我主路由器目前的状态&#xff0c;其中IP地址是我在上级光猫路由的可用ip段192.168.1.2~254里选的一个&#…

逆序对java_逆序对

求逆序对问题用归并排序的时间复杂度比暴力算法更低。假设有一个数组{8&#xff0c;1&#xff0c;2&#xff0c;5&#xff0c;7&#xff0c;4&#xff0c;3&#xff0c;6}首先归并排序第一次对数组进行分割 8 1 2 5 7 4 3 6二次分割 8 1 25 74 3…

python123测验9程序题答案_Django ORM 练习题及答案_python_脚本之家

1.modles中表结构#出版社class Publisher(models.Model):name models.CharField(max_length32)city models.CharField(max_length32)def __str__(self):return "".format(self.id, self.name)#书籍class Book(models.Model):title models.CharField(max_length32)…

java父类shape_为什么该父类无法调用其子类.__ShapeCircle_public_perimeter_getType_shapej__169IT.COM...

子类:public class ShapeCircle extends Shape{protected double r;public ShapeCircle(){setside(0.0);}public ShapeCircle(double r){setside(r);}public void setside(double r){this.rr;}public double perimeter(){return Math.PI*2*r;}public String getType(){return &…

python中双冒号的作用_python中双冒号

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

java电子通讯录毕业设计_(C)JAVA001电子通讯录(带系统托盘)

打开Server Socket,创建一个服务器型套接字和一个普通套接字&#xff0c;服务器型套接字在指定端口为客户端请求的Socket 服务&#xff1b;? 使用ServerSocket类的accept()方法使服务器型套接字处于监听状态并把监听结果返回给普通套接字&#xff1b;? 为该普通套接字创建输入…

python进行数据分析需要安装哪两个库_对Python进行数据分析_关于Package的安装问题...

一、为什么要使用Python进行数据分析&#xff1f;python拥有一个巨大的活跃的科学计算社区&#xff0c;拥有不断改良的库&#xff0c;能够轻松的集成C,C,Fortran代码(Cython项目)&#xff0c;可以同时用于研究和原型的构建以及生产系统的构建。二、Python的优势与劣势&#xff…

java orcl自动_Oracle自动生成编号

祝大家新年快乐&#xff0c;有任何问题可与我联系&#xff1a;今天用JAVA向Oracle数据库中插数据时&#xff0c;每次都要去计算ID&#xff0c;觉得好麻烦&#xff0c;于是想到了用数据库自带的ID来做&#xff0c;具体如下&#xff1a;1、首先得创建一序列序列(SEQUENCE)序列是一…