图像畸变矫正——透视变换
图像畸变矫正——透视变换
由于相机制造精度以及组装工艺的偏差引入的畸变,或者由于照片拍摄时的角度、旋转、缩放等问题, 可能会导致原始图像的失真,如果要修复这些失真,我们可以通过透视变换,对图像进行畸变矫正。
透视变换的原理推导
透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane), 也称作投影映射(Projective Mapping)。透视变换的目的就是把现实中为直线的物体, 在图片上可能呈现为斜线, 通过透视变换转换成直线的变换。
仿射变换(Affine Transformation或 Affine Map) , 又称为仿射映射, 是指在几何中, 图像进行从一个向量空间进行一次线性变换和一次平移, 变换为到另一个向量空间的过程。我们常说的仿射变换是透视变换的一个特例。
以上便是透视变换的原理图,即将源图像通过投影映射,从原图像平面变换到新图像平面。通用的变换公式为:
(X,Y,Z)是原图像平面坐标点, 对应得到变换后的图像平面坐标点为(X’;Y’;Z’) ,因为我们处理的是二维的图像,所以可以令Z’=1,并将变换后的图像坐标除以Z’,将图片由三维降维为两维,然后可以得到以下方程:
一般地, 我们令a33=1(方便得到X’,Y’,使方程3等号左侧分母为1), 展开上面公式, 得到一个点的情况:
方程3中共有8个未知数(aij),如果要解出该未知数,需要列八组方程,即分别在源图像和目标图像上人为选择四个点(通常选择图片的四个顶点)
在源图像上选四个坐标点,分别为A: (x0,y0),(x1,y1),(x2,y2),(x3,y3)
在目标图像上选四个坐标点,分别为B: (X’0,Y’0),(X’1,Y’1),(X’2,Y’2),(X’3,Y’3)
带入方程3,可以得出方程4,如下:
使用python,将上述推导过程定义为函数WarpPerspectiveMatrix(src, dst),计算出变换矩阵warpMatrix,如下:
import numpy as npdef WarpPerspectiveMatrix(src, dst):assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4#assert语句:用以检查某一条件是否为True,若该条件为False则会给出一个AssertionError。#注意这里src和dst的输入并不是图像,而是图像对应的顶点坐标点矩阵。nums = src.shape[0]A = np.zeros((2*nums, 8)) # A*warpMatrix=BB = np.zeros((2*nums, 1))for i in range(0, nums):A_i = src[i,:]B_i = dst[i,:]A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0,-A_i[0]*B_i[0], -A_i[1]*B_i[0]]B[2*i] = B_i[0]A[2*i+1, :] = [0, 0, 0, A_i[0], A_i[1], 1,-A_i[0]*B_i[1], -A_i[1]*B_i[1]]B[2*i+1] = B_i[1]A = np.mat(A) #创建矩阵#用A.I求出A的逆矩阵,然后与B相乘,求出warpMatrixwarpMatrix = A.I * B #求出a_11, a_12, a_13, a_21, a_22, a_23, a_31, a_32#之后为结果的后处理warpMatrix = np.array(warpMatrix).T[0] #np.array():创建一个数组,.T[0]:将Tensor进行转置warpMatrix = np.insert(warpMatrix, warpMatrix.shape[0], values=1.0, axis=0) #插入a_33 = 1'''np.insert(arr, obj, values, axis)#arr原始数组,可一可多,obj插入元素位置,values是插入内容,axis是按行按列插入。'''warpMatrix = warpMatrix.reshape((3, 3))return warpMatrixif __name__ == '__main__':'''#一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。# 因此 if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在 if __name__ == 'main': 下的代码只有在第一种情况下# (即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。'''print('warpMatrix')src = [[10.0, 457.0], [395.0, 291.0], [624.0, 291.0], [1000.0, 457.0]]src = np.array(src)dst = [[46.0, 920.0], [46.0, 100.0], [600.0, 100.0], [600.0, 920.0]]dst = np.array(dst)warpMatrix = WarpPerspectiveMatrix(src, dst)print(warpMatrix)
结果为:
warpMatrix
[[-5.01338334e-01 -1.35357643e+00 5.82386716e+02][-1.38100642e-15 -4.84035391e+00 1.38781980e+03][-2.29650079e-19 -4.14856327e-03 1.00000000e+00]]
上述推导过程是为了,让大家更加直观的的了解透视变换。在实际工程上,opencv库早已将上述过程集成为函数,我们选择网上流行的一张图片校验该opencv库中的畸变矫正算法。
代码块为:
import cv2
import numpy as npimg = cv2.imread('photo1.jpg')result3 = img.copy()#img = cv2.GaussianBlur(img,(3,3),0)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
"""
cv2.Canny(image, # 输入原图(必须为单通道图)threshold1, threshold2, # 较大的阈值2用于检测图像中明显的边缘[, edges[, apertureSize[, # apertureSize:Sobel算子的大小L2gradient ]]]) # 参数(布尔值):true: 使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开放),false:使用L1范数(直接将两个方向导数的绝对值相加)。
"""
edges = cv2.Canny(gray,50,150,apertureSize = 3)
#cv2.imwrite("canny.jpg", edges)'''
注意这里src和dst的输入并不是图像,而是图像对应的顶点坐标点矩阵。
'''
src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]])
dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]])
# 生成透视变换矩阵;进行透视变换
'''
1 cv2.getPerspectiveTransform(src, dst) → retval参数说明
src:源图像中待测矩形的四点坐标
sdt:目标图像中矩形的四点坐标
返回由源图像中矩形到目标图像矩形变换的矩阵
'''
m = cv2.getPerspectiveTransform(src, dst) #适用于一组点
'''
cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
参数为:
src:输入图像
M:变换矩阵
dsize:目标图像shape
flags:插值方式,interpolation方法INTER_LINEAR或INTER_NEAREST
borderMode:边界补偿方式,BORDER_CONSTANT or BORDER_REPLICATE
borderValue:边界补偿大小,常值,默认为0
'''
result = cv2.warpPerspective(result3, m, (337, 488)) #适用于图片
cv2.imshow("src", img)
cv2.imshow("result", result)
cv2.waitKey(0)
输出的结果为
图像畸变矫正——透视变换相关推荐
- 鱼眼图像畸变校正——透视变换
本文转自:[opencv]鱼眼图像畸变校正--透视变换 http://m.blog.csdn.net/article/details?id=50786782 原图 球面透视投影(以空间左手坐标系,x轴 ...
- (十三)图像畸变矫正
图像畸变矫正 针孔相机模型不考虑镜头畸变,因为一个理想的针孔相机没有镜头.但是由于相机的结构中存在着一些光学透镜,导致成像后的图像发生了扭曲,原本直立的高楼变得扭曲. 一.图像畸变原因 图像畸变的原因 ...
- VS2019+OpenCV4.5 鱼眼相机图像畸变矫正
一.鱼眼相机概述 鱼眼镜头是定焦镜头中的一种视野范围很大的镜头,它视角范围通常大于等于180度.鱼眼相机虽然能获得较大的视角范围,但是其拍摄的图像存在较大的畸变,为了后续任务的需要,往往需要对原始图像 ...
- 基于python opencv实现广角相机标定和图像畸变矫正
目的: 实现相机标定,得到相机的内参以及畸变旋转参数等 尝试矫正由相机产生的图像畸变 代码: import cv2 as cv import numpy as np import glob impor ...
- Python--Opencv工业广角相机图像畸变矫正
实现畸变矫正之前需要知道两个重要参数,一个是相机内参,另一个是畸变参数.只有拿到这两个参数之后才可矫正,获取方式是通过标定来实现. 一.标定并获取重要参数 标定不需要买标定板,只需要用一张白纸把下图 ...
- 图像畸变矫正 matlab,关于opencv图像畸变矫正
本文通过摄像头参数(fx,fy,cx,cy,k1,k2,p1,p2,p3(标定得到))去矫正摄像头拍出来的图像畸变详细代码在底部 首先 这里我们先介绍两个函数:他们都可以用来矫正畸变,但是一个是输入是 ...
- matlab图形矫正,图像畸变矫正算法实现 matlab版
真正的相机镜头不理想,并在图像中引入一些失真. 为了解释这些非理想性,有必要在透视投影的方程中添加失真模型. 一.原图如下: 二.实现的效果图 三.算法具体实现 function undistorte ...
- 【opencv】鱼眼图像畸变校正——透视变换
原图 球面透视投影(以空间左手坐标系,x轴为水平,y为竖直,z为光轴,投影面法线与xoz面夹角55度) 经过球面透视投影后,会存在两个灭点,此时,需要消去由于球面透视投影面存在角度引入的灭点.在这里采 ...
- 鱼眼图像畸变校正--透视变换
博客地址:https://blog.csdn.net/qq_15947787/article/details/50786782 源码下载地址:https://pan.baidu.com/s/1eShR ...
最新文章
- mongodb java findone_java-MongoRepository findOne使用“ id”代替“ _id”
- 玩游戏也能学Python?!论Python的正确打开方式
- 1006. Sign In and Sign Out (25)
- 机器学习系统设计——误差矩阵
- unit类型是什么?_项目中有用过锁吗?能解释一下什么是AQS(AbstractQueuedSynchronizer)吗?...
- 博客搬家到github啦
- silverlight 实现全屏
- win7下用UtralISO制作U盘系统盘--UltraISO打开Ubuntu只有EFI文件夹
- Expression Tree 扩展MVC中的 HtmlHelper 和 UrlHelper
- 【验证码识别】OpenCV挑战极验滑动拼图验证码
- android 简历
- Unity(三)EasyTouch5的使用
- oracle exadata x7发布,没有对比就没有伤害 QData T5完虐Oracle Exadata X7
- ArcGIS如何进行自动矢量化操作
- 月薪过2w的IT程序员都是怎么做到的?
- linux 深度 crossover,在Deepin V20(UOS)下使用crossover安装Kt交易师的方法
- Linux热潮下,来呆猫云工作站玩转云上部署Linux工作流新思路
- Python常见主流框架简介
- XSS相关:知其所以然—浏览器是如是解码的
- redis中hash数据结构