python opencv 实现透视变换——将侧视图进行正投影

这个方法可以将倾斜拍摄的四边形图片投影成矩形,在图像处理工程里经常要用,之前写过一个C语言版本的,可以搜我博客:透视变换

但是python语言版本的比较少,根据网上一些资料总结了一下。

废话不多说,直接上效果图。

效果图

原图

运行demo用,加深理解

代码

代码1——自动找四边形角点,然后透视变化

思路:
二值化——滤波——膨胀——腐蚀——找最外边轮廓——拟合四边形——四个顶点映射——透视变换

#(基于透视的图像矫正)
import cv2
import math
import numpy as npdef Img_Outline(input_dir):original_img = cv2.imread(input_dir)gray_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)blurred = cv2.GaussianBlur(gray_img, (1, 1), 0)                     # 高斯模糊去噪(设定卷积核大小影响效果)_, RedThresh = cv2.threshold(blurred, 165, 255, cv2.THRESH_BINARY)  # 设定阈值165(阈值影响开闭运算效果)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))          # 定义矩形结构元素closed = cv2.morphologyEx(RedThresh, cv2.MORPH_CLOSE, kernel)       # 闭运算(链接块)opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel)           # 开运算(去噪点)return original_img, gray_img, RedThresh, closed, openeddef findContours_img(original_img, opened):contours, hierarchy = cv2.findContours(opened, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#c = sorted(contours, key=cv2.contourArea, reverse=True)[1]   # 计算最大轮廓的旋转包围盒#rect = cv2.minAreaRect(c)                                    # 获取包围盒(中心点,宽高,旋转角度)#box = np.int0(cv2.boxPoints(rect))                           # box#box[]#draw_img = cv2.drawContours(original_img.copy(), [box], -1, (0, 0, 255), 3)draw_img=original_img.copy()cv2.drawContours(draw_img, contours, -1, (255, 0, 0), 2)#拟合四边形cnt_len = cv2.arcLength(contours[0], True)box = cv2.approxPolyDP(contours[0], 0.02 * cnt_len, True)if len(box) == 4:cv2.drawContours(draw_img, [box], -1, (255, 255, 0), 3)'''box[0]: [[163  32]]右上box[1]: [[63 72]]   左上box[2]: [[150 215]]左下box[3]: [[268 144]]右下'''print("box[0]:", box[0])print("box[1]:", box[1])print("box[2]:", box[2])print("box[3]:", box[3])# for i in range(len(box)):#     box_after[i]=box[3-i]box_after =[0]*4#排好序的角点输出,0号是左上角,顺时针输出box_after[0] = box[1]box_after[1] = box[0]box_after[2] = box[3]box_after[3] = box[2]print("box_after[0]:", box_after[0])print("box_after[1]:", box_after[1])print("box_after[2]:", box_after[2])print("box_after[3]:", box_after[3])return box_after,draw_img#return draw_img
def Perspective_transform(box,original_img):# # 获取画框宽高(x=orignal_W,y=orignal_H)# orignal_W = math.ceil(np.sqrt((box[3][1] - box[2][1])**2 + (box[3][0] - box[2][0])**2))# orignal_H= math.ceil(np.sqrt((box[3][1] - box[0][1])**2 + (box[3][0] - box[0][0])**2))## # 原图中的四个顶点,与变换矩阵# pts1 = np.float32([box[0], box[1], box[2], box[3]])# pts2 = np.float32([[int(orignal_W+1),int(orignal_H+1)], [0, int(orignal_H+1)], [0, 0], [int(orignal_W+1), 0]])## # 生成透视变换矩阵;进行透视变换# M = cv2.getPerspectiveTransform(pts1, pts2)# result_img = cv2.warpPerspective(original_img, M, (int(orignal_W+3),int(orignal_H+1)))#ROTATED_SIZE_W = 600  # 透视变换后的表盘图像大小ROTATED_SIZE_H = 800  # 透视变换后的表盘图像大小# 原图中书本的四个角点(左上、右上、右下、左下),与变换后矩阵位置#pts1 = np.float32([[63, 72], [163, 32], [268, 144], [150, 215]])pts1 = np.float32([box[0], box[1], box[2], box[3]])# 变换后矩阵位置pts2 = np.float32([[0, 0], [ROTATED_SIZE_W, 0], [ROTATED_SIZE_W, ROTATED_SIZE_H], [0, ROTATED_SIZE_H], ])# 生成透视变换矩阵;进行透视变换M = cv2.getPerspectiveTransform(pts1, pts2)result_img = cv2.warpPerspective(original_img, M, (ROTATED_SIZE_W, ROTATED_SIZE_H))return result_imgif __name__=="__main__":input_dir = "./1.jpg"original_img, gray_img, RedThresh, closed, opened = Img_Outline(input_dir)box, draw_img = findContours_img(original_img,opened)#draw_img = findContours_img(original_img, opened)result_img = Perspective_transform(box,original_img)cv2.imshow("original", original_img)cv2.imshow("gray", gray_img)cv2.imshow("closed", closed)cv2.imshow("opened", opened)cv2.imshow("draw_img", draw_img)cv2.imshow("result_img", result_img)cv2.waitKey(0)cv2.destroyAllWindows()

代码2——手动输入四个角点,然后进行透视变换

'''
box[0]: [[163  32]]右上
box[1]: [[63 72]]   左上
box[2]: [[150 215]]左下
box[3]: [[268 144]]右下
'''import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('1.jpg')ROTATED_SIZE  = 600 #透视变换后的表盘图像大小
CUT_SIZE     =  0   #透视变换时四周裁剪长度W_cols, H_rows= img.shape[:2]
print(H_rows, W_cols)# 原图中书本的四个角点(左上、右上、右下、左下),与变换后矩阵位置,排好序的角点输出,0号是左上角,顺时针输出
pts1 = np.float32([[63, 72], [163, 32], [268, 144], [150, 215]])
#变换后矩阵位置
pts2 = np.float32([[0, 0],[ROTATED_SIZE,0],[ROTATED_SIZE, ROTATED_SIZE],[0,ROTATED_SIZE],])# 生成透视变换矩阵;进行透视变换
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (ROTATED_SIZE,ROTATED_SIZE))cv2.imshow("original_img",img)
cv2.imshow("result",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考文章;
1、Python-Opencv基于透视变换的图像矫正
2、opencv 四边形拟合_谈谈OpenCV中的四边形

python opencv 实现透视变换——将侧视图进行正投影相关推荐

  1. 【Python+OpenCV 图像透视变换 warpPerspective函数】

    Python+OpenCV 图像透视变换 warpPerspective函数 1.函数介绍 2.代码实例 3.实现效果 1.函数介绍 warpPerspective():对图像进行透视变换.简单来说, ...

  2. python写透视挂_如何用Python openCV 用透视变换的方法对图像进行矫正

    .需要矫正的图片1 需要矫正的图 矫正后的结果: 矫正后的图 需要矫正的图片2 矫正前 矫正后 # import the necessary packages from imutils.perspec ...

  3. 文档扫描仪的构建——使用Python,OpenCV应用透视变换来获得图像的自顶向下的“鸟瞰图”

    使用Python,OpenCV应用透视变换来获得图像的自顶向下的"鸟瞰图" 1. 效果图 2. 应用透视变换的步骤 3. 优化:矩形角点的获取 4. 源码 参考 这篇博客演示了如何 ...

  4. (九)相机内参、外参、反透视变换python opencv

    背景知识 任务需求:将相机上的一个点投影到真实世界平面上去. 原则上单目相机是不可以的,因为只记录了二维信息,真实世界是三维的,双目相机可以通过视差,或者单目+IMU组合,但是由于特征点在地面上的先验 ...

  5. python+opencv图像拼接-python opencv 图像拼接的实现方法

    初级的图像拼接为将两幅图像简单的粘贴在一起,仅仅是图像几何空间的转移与合成,与图像内容无关.高级图像拼接也叫作基于特征匹配的图像拼接,拼接时消去两幅图像相同的部分,实现拼接合成全景图. 具有相同尺寸的 ...

  6. 基于python+opencv的图像目标区域自动提取

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 一.提取纸张中的内容 一张照片中的感兴趣区域总是沿着x,y,z三个轴都有一定倾斜(如下图),要 ...

  7. Python + OpenCV + DeepLearning 解数独问题【一、数独的提取】

    整个解数独问题可以大致分为3个部分: 从图片中提取出完整的数独[本文的部分] 从数独中提取出数字并传入神经网络进行预测 解出数独 [环境] Python:3.8.5 OpenCV:4.5.1 Kera ...

  8. python opencv 条形码及二维码检测识别

    目录 条形码检测识别 二维码检测识别 基于python opencv pyzbar 实现. 条形码检测识别 原图: 最后截取图: 直接上代码: import cv2 import numpy as n ...

  9. python+opencv实现多张图像拼接_附源码

    文章目录 前言 完整源码 下载链接:[https://download.csdn.net/download/DeepLearning_/87290571](https://download.csdn. ...

最新文章

  1. 电源符号VCC、VDD、VEE、VSS都是什么意思?有何区别?
  2. gson 的简单使用
  3. 关于接口 RandomAccess
  4. 从程序员到项目经理(二十九):怎样写文档
  5. C语言学习笔记(4)
  6. Azure Virtual Network, 虚拟网络
  7. python画曲线图-python绘制多个曲线的折线图
  8. 请求重定向与请求转发的区别
  9. hdu 6096 String(AC自动机巧妙建图)
  10. tkinter中控件menu的两种组织方法
  11. Nginx if语句配置多重判断
  12. 5G基站到底长啥样?和4G有啥区别?
  13. P1039 [NOIP2003 提高组] 侦探推理
  14. outlook邮箱邮件大小限制_附件大小超过了允许的限制错误 - Outlook | Microsoft Docs...
  15. .NET中Hangfire快速入门和使用-迷恋自留地
  16. 浅谈计算机应用的认识,浅谈《计算机应用基础》教学
  17. 6.1 Python图像处理之图像编码技术和标准-DPCM编码
  18. Luogu P3385 【模板】负环 - 题解
  19. 微博评论爬虫 | 情感分析 | 词云图展示
  20. 下载YouTube视频的一种方法

热门文章

  1. paramiko下载文件夹
  2. 物联网流量池_物联网卡流量池
  3. app能不能跳转外部h5_APP内部H5页面跳转 H5唤起APP 怎么做?
  4. Web实现:装饰边框添加阴影
  5. 斐讯N1刷armbian
  6. 欧式几何与非欧式几何
  7. 面经——2019求职修行记
  8. 国美GOME U7 启用自带fm收音机功能,无需流量和wifi便可畅听广播.2021-12-23
  9. VS CODE利用SSH连接远程服务器
  10. 如何保证库存数量及时