Python Opencv基于透视变换的图像矫正

作者:Python之魂 时间:2022-03-13 16:47:14 

本文实例为大家分享了Python Opencv基于透视变换的图像矫正,供大家参考,具体内容如下

一、自动获取图像顶点变换(获取图像轮廓顶点矫正)

图像旋转校正思路如下

1、以灰度图读入
2、腐蚀膨胀,闭合等操作
3、二值化图像
4、获取图像顶点
5、透视矫正

#(基于透视的图像矫正)
import cv2
import math
import numpy as np

def Img_Outline(input_dir):
    original_img = cv2.imread(input_dir)
    gray_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray_img, (9, 9), 0)                     # 高斯模糊去噪(设定卷积核大小影响效果)
    _, RedThresh = cv2.threshold(blurred, 165, 255, cv2.THRESH_BINARY)  # 设定阈值165(阈值影响开闭运算效果)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))          # 定义矩形结构元素
    closed = cv2.morphologyEx(RedThresh, cv2.MORPH_CLOSE, kernel)       # 闭运算(链接块)
    opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel)           # 开运算(去噪点)
    return original_img, gray_img, RedThresh, closed, opened

def findContours_img(original_img, opened):
    image, contours, hierarchy = cv2.findContours(opened, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    c = sorted(contours, key=cv2.contourArea, reverse=True)[1]   # 计算最大轮廓的旋转包围盒
    rect = cv2.minAreaRect(c)                                    # 获取包围盒(中心点,宽高,旋转角度)
    box = np.int0(cv2.boxPoints(rect))                           # box
    draw_img = cv2.drawContours(original_img.copy(), [box], -1, (0, 0, 255), 3)

    print("box[0]:", box[0])
    print("box[1]:", box[1])
    print("box[2]:", box[2])
    print("box[3]:", box[3])
    return box,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)))

    return result_img

if __name__=="__main__":
    input_dir = "../staticimg/oldimg_04.jpg"
    original_img, gray_img, RedThresh, closed, opened = Img_Outline(input_dir)
    box, 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()

直接变换

1、获取图像四个顶点
2、形成变换矩阵
3、透视变换

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('original_img.jpg')
H_rows, W_cols= img.shape[:2]
print(H_rows, W_cols)

# 原图中书本的四个角点(左上、右上、左下、右下),与变换后矩阵位置
pts1 = np.float32([[161, 80], [449, 12], [1, 430], [480, 394]])
pts2 = np.float32([[0, 0],[W_cols,0],[0, H_rows],[H_rows,W_cols],])

# 生成透视变换矩阵;进行透视变换
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (500,470))

"""
注释代码同效
# img[:, :, ::-1]是将BGR转化为RGB
# plt.subplot(121), plt.imshow(img[:, :, ::-1]), plt.title('input')
# plt.subplot(122), plt.imshow(dst[:, :, ::-1]), plt.title('output')
# plt.show
"""

cv2.imshow("original_img",img)
cv2.imshow("result",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

两次透视变换

def get_warp_perspective(img, width, height, array_points, array_points_get, array_points_warp):
    middle_len = 268
    # rows, cols = img.shape[:2]
    # D_value1 = (middle_len - array_points_get[0][1])*2+((middle_len - array_points_get[0][1])//3)
    # D_value2 = (middle_len - array_points_get[1][1])*2+((middle_len - array_points_get[1][1])//3)
    D_value1 = 0
    D_value2 = 0
    # 原图中的四个角点
    # pts1 = np.float32([[0, 249],[512, 253],[0, 512], [512, 512]])#重要的测试1和2
    pts1 = np.float32(array_points_get)#重要的测试1和2

    # pts2 = np.float32([[0, middle_len], [width, middle_len], [0, height], [width, height]])#重要的测试1和2
    # pts2 = np.float32([[0, middle_len],[0, height] , [width, height],[width, middle_len]])#重要的测试1和2
    pts2 = np.float32([[0, 0],[0, middle_len] , [width, middle_len],[width, 0]])#重要的测试1和2

    # 生成透视变换矩阵
    M = cv2.getPerspectiveTransform(pts1, pts2)
    # 进行透视变换
    dst = cv2.warpPerspective(img, M, (width, height))
    # # 保存图片,仅用于测试
    img_path = './cut_labels/cut_image_one.jpg'
    cv2.imwrite(img_path, dst)

    return warp_perspective(dst, width, height,array_points,array_points_warp,middle_len, D_value1, D_value2)

def warp_perspective(dst, width, height,array_points,array_points_warp,middle_len, D_value1, D_value2):
    # new_img_path = img_path
    # img = cv2.imread(new_img_path)
    # 原图的保存地址
    # rows, cols = img.shape[:2]

    # 原图中的四个角点
    # pts3 = np.float32([[0, 268], [0, 44], [512,35], [512, 268]])#重要测试1
    # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要测试1
    pts3 = np.float32([[0, 0], [0, height], [width, height], [width, 0]])
    # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要测试1
    # pts3 = np.float32([[0, 512], [0, array_points[1][1]], [512,512], [512, middle_len]])#重要测试1
    # 变换后的四个角点
    pts4 = np.float32([[0, 0], [0, height-D_value1], [width, height-D_value2], [width, 0]])#重要测试1
    # pts4 = np.float32([[0, 268], [0, 0], [512, 0], [512, 268]])#重要测试1
    # 生成透视变换矩阵
    M = cv2.getPerspectiveTransform(pts3, pts4)
    # 进行透视变换
    dst_img = cv2.warpPerspective(dst, M, (width, height))
    # #保存最终图片,仅用于测试
    print("++++++++++++++++")
    final_img_path = './cut_labels/cut_image_two.jpg'
    cv2.imwrite(final_img_path, dst_img)
    # 进行透视变换
    return cv2.warpPerspective(dst_img, M, (width, height))
    # return output_warp_perspective(img, width, height, array_points, array_points_get, array_points_warp)

if __name__  == "__main__":
    # 透视转换
       img = cv2.imread('../staticimg/oldimg_04.jpg')
     dst = get_warp_perspective(img, 512, 512, array_points=[[395.2, 75.0], [342, 517], [1000, 502], [900, 75]])
     cv2.imwrite('aaa2.jpg', dst)
     cv2.imshow('title', dst)
     cv2.waitKey(0)
     imgrectificate = imgRectificate(img, width, height, array_points)
     imgrectificate.warp_perspective()

来源:https://blog.csdn.net/weixin_43431189/article/details/93513923

标签:Python,Opencv,图像矫正
0
投稿

猜你喜欢

  • Python抓取框架Scrapy爬虫入门:页面提取

    2022-04-16 18:57:47
  • 彻底搞懂MySQL存储过程和函数

    2024-01-24 10:48:52
  • Python 使用dict实现switch的操作

    2021-12-28 02:47:52
  • Python深拷贝与浅拷贝用法实例分析

    2023-11-06 01:25:04
  • mysql设置指定ip远程访问连接实例

    2024-01-26 04:36:36
  • Windows64x下VScode下载过程

    2021-03-08 20:10:47
  • Playwright快速上手指南(入门教程)

    2022-09-25 02:44:23
  • python 列表,集合和字典的增删改查

    2021-06-20 04:31:37
  • Python语言实现获取主机名根据端口杀死进程

    2023-07-01 10:05:58
  • php实现比较全的数据库操作类

    2023-11-22 02:15:10
  • Python实现简单的文件传输与MySQL备份的脚本分享

    2024-01-21 04:44:44
  • 在pyqt5中展示pyecharts生成的图像问题

    2023-10-17 10:59:46
  • python操作MySQL数据库的方法分享

    2024-01-13 16:11:54
  • Flask 入门系列 Cookie与session的介绍

    2022-06-21 00:45:44
  • python继承threading.Thread实现有返回值的子类实例

    2023-06-07 19:01:15
  • Python读取表格类型文件代码实例

    2023-08-24 22:04:16
  • 详解如何用Python写个听小说的爬虫

    2021-09-04 09:56:09
  • ORACLE数据库应用开发常见问题及排除

    2010-07-26 13:17:00
  • 利用Django框架中select_related和prefetch_related函数对数据库查询优化

    2024-01-20 23:24:19
  • mysql数据库中的索引类型和原理解读

    2024-01-19 20:48:17
  • asp之家 网络编程 m.aspxhome.com