ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[图片校准(矫正)]——透射变换应用

2021-09-03 22:04:39  阅读:189  来源: 互联网

标签:矫正 校准 int pts 透射 cv2 points np oshape


如果想要对图像进行校准,那么透射变换是非常有效的变换方法。

  • 透射变换的定义如下:将图像投影到一个新的视平面,通常也成为投影映射。
  • 详情参考链接:透射变换介绍

1、举例说明 

直观的来看,透视变换的作用就是将左侧图像的坐标点 [[50,0],[150,0],[0,200],[200,200]]
转化为新的坐标 [[0,0],[200,0],[0,200],[200,200]]

 2、应用

原图是一个旋转过的图片,现在需要做图片矫正,将图片放正。

  • 做法:手工选去需要矫正区域四个角上的点(顺序:左上、右上、右下、左下),使用透射变换对所选区域进行矫正

原图如下:

 代码:

import numpy as np
import cv2

def order_points(pts):
    # 初始化坐标点
    rect = np.zeros((4, 2), dtype="float32")

    # 获取左上角和右下角坐标点
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]

    # 分别计算左上角和右下角的离散差值
    diff = np.diff(pts, axis=1)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]

    return rect


def four_point_transform(image, pts):
    """
    :param image: 图片
    :param pts: 鼠标选中的点集
    :return: 返回变换后的图片
    """
    # 获取坐标点,并将它们分离开来
    rect = order_points(pts)
    (tl, tr, br, bl) = rect

    # 计算新图片的宽度值,选取水平差值的最大值
    widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
    widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
    maxWidth = max(int(widthA), int(widthB))

    # 计算新图片的高度值,选取垂直差值的最大值
    heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
    heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
    maxHeight = max(int(heightA), int(heightB))

    # 构建新图片的4个坐标点
    dst = np.array([
        [0, 0],
        [maxWidth - 1, 0],
        [maxWidth - 1, maxHeight - 1],
        [0, maxHeight - 1]], dtype="float32")

    # 获取仿射变换矩阵并应用它
    M = cv2.getPerspectiveTransform(rect, dst)
    # 进行仿射变换
    warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))

    # 返回变换后的结果
    return warped


def on_mouse(event, x, y, flags, param):
    global timg, points
    img2 = timg.copy()
    point0 = (0, 0)
    if event == cv2.EVENT_LBUTTONDOWN:  # 左键点击
        point1 = (x, y)
        points.append([x, y])
        #print(x, y)
        cv2.circle(img2, point1, 4, (0, 255, 0), 4)
        cv2.imshow('origin', img2)
    return point0


#程序获取需要矫正的区域
def rectification(img_file, points):
    xscale, yscale = 0.9, 0.9
    oimg = cv2.imread(img_file)
    oshape = oimg.shape
    timg = cv2.resize(oimg, (int(oshape[1] / xscale), int(oshape[0] / yscale)))  # 放大图像
    points = np.array(points, dtype=np.float32)
    points[:, 0] *= oshape[1] / int(oshape[1] / xscale)  # 还原像素位置的大小
    points[:, 1] *= oshape[0] / int(oshape[0] / yscale)
    warped = four_point_transform(oimg, points)
    cv2.imwrite('images/final.png', warped ) # 保存图像
    cv2.imshow('final', warped)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

#手工选择区域进行图片矫正
def image_rectification(img_file):
    global points, timg
    #xscale, yscale = 0.5, 0.5  # 通过放大图像来使得点击位置更加精确
    xscale, yscale = 0.9, 0.9
    points = []
    oimg = cv2.imread(img_file)
    oshape = oimg.shape #图形规格
    timg = cv2.resize(oimg, (int(oshape[1] / xscale), int(oshape[0] / yscale)))  # 放大图像
    print(timg.shape)
    cv2.imshow('origin', timg)
    cv2.setMouseCallback('origin', on_mouse)
    cv2.waitKey(0)  # 点完4个角点之后随便按一个键盘按键结束操作
    cv2.destroyAllWindows()
    points = np.array(points, dtype=np.float32)
    points[:, 0] *= oshape[1] / int(oshape[1] / xscale)  # 还原像素位置的大小
    points[:, 1] *= oshape[0] / int(oshape[0] / yscale)
    warped = four_point_transform(oimg, points)
    # cv2.imwrite('warped.png', warped ) # 保存图像
    cv2.imshow('origin', warped)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == '__main__':
    points = []
    rectification('images/test.png', points)

 矫正后的图片:

标签:矫正,校准,int,pts,透射,cv2,points,np,oshape
来源: https://blog.csdn.net/weixin_42067873/article/details/120090882

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有