python图像处理:透视变换

python图像处理:透视变换

原理

透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。通用的变换公式为:
在这里插入图片描述

u,v是原始图片坐标,对应得到变换后的图片坐标x,y,其中。
变换矩阵在这里插入图片描述可以拆成4部分,在这里插入图片描述表示线性变换,比如scaling,shearing和ratotion。在这里插入图片描述用于平移,在这里插入图片描述产生透视变换。所以可以理解成仿射等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。

重写之前的变换公式可以得到:
在这里插入图片描述

所以,已知变换对应的几个点就可以求取变换公式。反之,特定的变换公式也能新的变换后的图片。简单的看一个正方形到四边形的变换:
变换的4组对应点可以表示成:
在这里插入图片描述
根据变换公式得到:
在这里插入图片描述

定义几个辅助变量:
在这里插入图片描述

都为0时变换平面与原来是平行的,可以得到:
在这里插入图片描述

不为0时,得到:
在这里插入图片描述

求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。

原理来自于这篇文章

效果

在这里插入图片描述

代码

先给出测试用图,坐标是手动标定的,在代码里。
在这里插入图片描述

import cv2 
import numpy as np 

def order_points(pts):
	#顺时针排列点
	#topleft,topright,bottomleft,bottomright
    rect = np.zeros((4,2),dtype='float32')
    
    s = pts.sum(axis = 1)
    rect[0] = pts[np.argmin(s)]
    rect[3] = pts[np.argmax(s)]

    d =  np.diff(pts,axis = 1)
    rect[1] = pts[np.argmin(d)]
    rect[2] = pts[np.argmax(d)]

    return rect

def four_point_transform(image,pts):
    rect = order_points(pts)
    (tl,tr,bl,br) = rect

    widthA = np.sqrt((tl[0] - tr[0])**2 + (tl[1] - tr[1])**2)
    widthB = np.sqrt((bl[0] - br[0])**2 + (bl[1] - br[1])**2)
    width = int(max(widthA,widthB))

    heightA = np.sqrt((tl[0] - bl[0])**2 + (tr[1] - br[1])**2)
    heightB = np.sqrt((tl[0] - bl[0])**2 + (tr[1] - br[1])**2)
    height = int(max(heightA,heightB))

    dst = np.array([[0,0],[width-1,0],[width-1,height-1],[0,height-1]],dtype='float32')

	#变换矩阵交给cv2去算啦
    M = cv2.getPerspectiveTransform(pts,dst)
    wraped = cv2.warpPerspective(image,M,(width,height))
    return wraped
    
img = cv2.imread('card.jpg')
c = np.array([[280,254],[668,443],[532,694],[127,485]],dtype='float32')
img_t = four_point_transform(img,c)
cv2.imshow('origin',img)
cv2.imshow('transformed',img_t)
cv2.waitKey(0)
cv2.destroyAllWindows()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值