利用Python将图片中扭曲矩形的复原


Posted in Python onSeptember 07, 2020

前言

日常生活中,手残党们经常会把一些照片拍歪,比如拍个证件、试卷、PPT什么的,

比如下面这本书的封面原本是个矩形,随手一拍就成了不规则四边形

想要把它变成规则的矩形,有什么办法呢?

利用Python将图片中扭曲矩形的复原

你一定想到了 PS,因为网上很多教程就是这么教的

打开PS ⟹\Longrightarrow⟹ 滤镜 ⟹\Longrightarrow⟹镜头校正 ⟹\Longrightarrow⟹自定 ⟹\Longrightarrow⟹变换

可是这样手工的调整数值实在是费劲哟!!

利用Python将图片中扭曲矩形的复原

下面我们来写个程序,自动将图片恢复到任意矩形!

程序实现

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. 在图片中标记四个角点

利用Python将图片中扭曲矩形的复原

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)

结果如下

利用Python将图片中扭曲矩形的复原

结果没有想象的完美,是因为书的封面已经不是一个平面了,书角翘起。。。

如果图片中的矩形在一个平面上的话,效果还是挺不错的!!

利用Python将图片中扭曲矩形的复原

完整代码下载

可关注后免费下载喔:https://download.csdn.net/download/itnerd/12819535(本地下载)

总结

到此这篇关于利用Python将图片中扭曲矩形复原的文章就介绍到这了,更多相关Python图片扭曲矩形复原内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python中测试访问同一数据的竞争条件的方法
Apr 23 Python
讲解Python中的标识运算符
May 14 Python
python关键字and和or用法实例
May 28 Python
Python实现字典的key和values的交换
Aug 04 Python
Python3控制路由器——使用requests重启极路由.py
May 11 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
Jul 04 Python
Python金融数据可视化汇总
Nov 17 Python
python 搭建简单的http server,可直接post文件的实例
Jan 03 Python
python使用matplotlib画柱状图、散点图
Mar 18 Python
如何使用Python自动控制windows桌面
Jul 11 Python
Python 脚本拉取 Docker 镜像问题
Nov 10 Python
python每5分钟从kafka中提取数据的例子
Dec 23 Python
python利用递归方法实现求集合的幂集
Sep 07 #Python
Python描述数据结构学习之哈夫曼树篇
Sep 07 #Python
python简单利用字典破解zip文件口令
Sep 07 #Python
python 如何快速复制序列
Sep 07 #Python
Python2与Python3关于字符串编码处理的差别总结
Sep 07 #Python
python 装饰器的实际作用有哪些
Sep 07 #Python
通俗讲解python 装饰器
Sep 07 #Python
You might like
php提示Call-time pass-by-reference has been deprecated in的解决方法[已测]
2012/05/06 PHP
smarty模板引擎中内建函数if、elseif和else的使用方法
2015/01/22 PHP
php随机抽奖实例分析
2015/03/04 PHP
实例详解PHP中html word 互转的方法
2016/01/28 PHP
php提交过来的数据生成为txt文件
2016/04/28 PHP
JavaScript中两种链式调用实现代码
2011/01/12 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
JavaScript实现鼠标滑过处生成气泡的方法
2015/05/16 Javascript
利用jQuery.Validate异步验证用户名是否存在(推荐)
2016/12/09 Javascript
微信小程序(三):网络请求
2017/01/13 Javascript
js实现PC端根据IP定位当前城市地理位置
2017/02/22 Javascript
浅谈regExp的test方法取得的值变化的原因及处理方法
2017/03/01 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
OkHttp踩坑随笔为何 response.body().string() 只能调用一次
2018/01/08 Javascript
Vue.js 利用v-for中的index值实现隔行变色
2018/08/01 Javascript
深入理解NodeJS 多进程和集群
2018/10/17 NodeJs
jQuery实现动态添加和删除input框代码实例
2019/03/29 jQuery
基于three.js实现的3D粒子动效实例代码
2019/04/09 Javascript
JS解惑之Object中的key是有序的么
2019/05/06 Javascript
使用vue重构资讯页面的实例代码解析
2019/11/26 Javascript
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
python冒泡排序算法的实现代码
2013/11/21 Python
简单上手Python中装饰器的使用
2015/07/12 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
基于matplotlib xticks用法详解
2020/04/16 Python
python 监控logcat关键字功能
2020/09/04 Python
财务部经理岗位职责
2014/02/03 职场文书
党员公开承诺书和承诺事项
2014/03/25 职场文书
企业党员一句话承诺
2014/05/30 职场文书
单位接收函格式
2015/01/30 职场文书
教师个人总结范文
2015/02/11 职场文书
开会通知
2015/04/20 职场文书
小学教育见习总结
2015/06/23 职场文书
TV动画「神渣☆爱豆」公开第一弹主视觉图
2022/03/21 日漫
ssh服务器拒绝了密码 请再试一次已解决(亲测有效)
2022/08/14 Servers