利用Python将图片中扭曲矩形的复原
作者:颹蕭蕭 发布时间:2022-05-24 21:35:54
标签:python,图片,复原
前言
日常生活中,手残党们经常会把一些照片拍歪,比如拍个证件、试卷、PPT什么的,
比如下面这本书的封面原本是个矩形,随手一拍就成了不规则四边形
想要把它变成规则的矩形,有什么办法呢?
你一定想到了 PS,因为网上很多教程就是这么教的
打开PS⟹\Longrightarrow⟹ 滤镜⟹\Longrightarrow⟹镜头校正⟹\Longrightarrow⟹自定⟹\Longrightarrow⟹变换
可是这样手工的调整数值实在是费劲哟!!
下面我们来写个程序,自动将图片恢复到任意矩形!
程序实现
1. 打开图片并显示
import cv2 as cv
import numpy as np
path = './book.jpg'
src = cv.imread(path)
def get_window_size(src, bound=600):
h,w = src.shape[0], src.shape[1]
if h > w:
h, w = bound, int(w*bound/h)
else:
h, w = int(h*bound/w), bound
return (h, w)
h, w = get_window_size(src)
win_name = 'RecAdjust'
cv.namedWindow(win_name, cv.WINDOW_NORMAL)
cv.resizeWindow(win_name, width=w, height=h)
cv.imshow(win_name, src)
cv.waitKey(0)
cv.destroyAllWindows()
2. 在图片中标记四个角点
src_copy = src.copy()
class Indexer:
def __init__(self, bound=4):
self.id = 0
self.bound=bound
def get_id(self):
self.id = (self.id+1)%self.bound
return (self.id-1)%self.bound+1
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDOWN:
img = param['src']
win_name = param['window']
indexer = param['indexer']
points = param['points']
curr_id = indexer.get_id()
points.append((x,y))
print('第{}个顶点: ({},{})'.format(curr_id, x, y))
cv.circle(img, (x, y), 10, (0, 0, 255), thickness = 2)
cv.putText(
img,
str(curr_id), # 文字
(x, y), # 坐标
cv.FONT_HERSHEY_PLAIN,
5, # 字号
(0,0,255), # 字体颜色
thickness = 2 # 粗细
)
cv.imshow(win_name, img)
points = []
indexer = Indexer()
win_name = 'RecAdjust'
cv.namedWindow(win_name, cv.WINDOW_NORMAL)
cv.resizeWindow(win_name, width=w, height=h)
cv.imshow(win_name, src)
cv.setMouseCallback(win_name, on_EVENT_LBUTTONDOWN, param={'src':src,'window':win_name, 'indexer':indexer, 'points':points})
cv.waitKey(0)
cv.destroyAllWindows()
print(points)
3. 设定输出矩形大小
# W = int(input('输出图片宽度:'))
# H = int(input('输出图片高度:'))
W,H = 600, 800
target_points = [(0,0),(W,0),(W,H),(0,H)]
4. 求解透视变换矩阵
points, target_points = np.array(points, dtype=np.float32), np.array(target_points, dtype=np.float32)
M = cv.getPerspectiveTransform(points, target_points)
print('透视变换矩阵:',M)
5. 透视变换并保存图片
result = cv.warpPerspective(src_copy, M, (0, 0))
result = result[:H, :W]
win_name = 'Result'
cv.namedWindow(win_name, cv.WINDOW_NORMAL)
cv.resizeWindow(win_name, width=W, height=H)
cv.imshow(win_name, result)
cv.waitKey(0)
cv.destroyAllWindows()
output_file = 'result.jpg'
cv.imwrite(output_file, result)
结果如下
结果没有想象的完美,是因为书的封面已经不是一个平面了,书角翘起。。。
如果图片中的矩形在一个平面上的话,效果还是挺不错的!!
完整代码下载
可关注后免费下载喔:https://download.csdn.net/download/itnerd/12819535(本地下载)
来源:https://blog.csdn.net/itnerd/article/details/108429553


猜你喜欢
- 今天在看文档的时候,发现pytorch 的conv操作不是很明白,于是有了一下记录首先提出两个问题:1.输入图片是单通道情况下的filter
- 头疼的挂马事件申请了个免费空间弄了个小站空间还可以二年多了挺稳定的只是从今年年初开始网页老莫名奇妙的被人挂马仔细检查了网站 不存在什么漏洞应
- 你可以按照以下方法使用 ls 命令来查看你的系统中都有那些 Python 的二进制文件可供使用。$ ls /usr/bin/python*/
- CREATE TABLE table1( [ID] [bigint] IDENTITY(1,1) NOT NULL, [Name] [nva
- 1.断点调试是啥?难不难?断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下
- 本文实例为大家分享了vue实现购物车加减的具体代码,供大家参考,具体内容如下通常我们会在模板中绑定表达式,模板是用来描述视图结构的。如果模板
- 机器A: select instance_name from v$instance; select name from v$database
- 使用ASP处理XSLT转换XML比较简单,思路如下:创建一个XSLTemplate的对象,再创建一个XMLDOM对象,然后在家Xml文件和X
- csv是Comma-Separated Values的缩写,是用文本文件形式储存的表格数据,比如如下的表格:就可以存储为csv文件,文件内容
- 开源数据库架构设计原则01. 技术选型选择成熟的平台和技术,同时是最熟悉的,能做到极致的,用好不用坏,用熟不用生。目前业界的MySQL主流分
- 本文是在上篇文章Python中的type和object,做的补充,希望大家喜欢。这篇博客主要描述Python的新风格对象(new-style
- 前言一直想好好学习一下Python爬虫,之前断断续续的把Python基础学了一下,悲剧的是学的没有忘的快。只能再次拿出来滤了一遍,趁热打铁,
- 我就废话不多说了,大家还是直接看代码吧~# 用一行代码实现for循环初始化数组o = 10b = [ o + u for u in rang
- 记得以前的windows 任务定时是可以的正常使用的,今天试了下,发现不能正常使用了,任务计划总是挂起。接下来记录下python 爬虫定时任
- 本文介绍了vue 模拟后台数据(加载本地json文件)调试,分享给大家,也给自己留个笔记首先创建一个本地json文件,放在项目中如下{ &q
- 在我们的日常工作自动化测试当中,几乎超过一半的功能都需要利用定时的任务来推动触发,例如在我们项目中有一个定时监控模块,根据自己设置的频率定时
- Python爬虫可以爬取的东西有很多,Python爬虫怎么学?简单的分析下:如果你仔细观察,就不难发现,懂爬虫、学习爬虫的人越来越多,一方面
- 安装淘宝镜像:要安装Angular4。于是我对着一股浓郁口音的视频开启了Angular4安装之旅。那口音说了,ang哥乐4不是那么好装的,由
- SecureFile功能是oracle 11g中对大对象(LOB)存储格式的完全重新设计实现,原来的LOB存储格式现在通称为BASIXFIL
- 前言:如果使用进到的日志文件方法:logging.FileHandler,会导致日志信息全部存放在一个日志文件中,不利于后面对日志文件的使用