【懒懒的计算机视觉笔记之单应性变换】
2018-01-15 22:21
671 查看
最近一直在学习Python计算机视觉编程中图像到图像之间的映射,这些变化可以用于图像扭曲变形和图像配准。所谓单应性变换就是将一个平面内的点映射到另一个平面内的二维投影变换。单应性变换具有很强的实用性,比如图像配准、图像纠正和纹理扭曲,以及创建全景图像等。其实,单应性变换H,是按照下面的公式映射二维中的点(其次坐标意义下):
齐次坐标是在实际应用中非常有用的表达式,点的齐次坐标依赖其尺度定义,所以x=[x,y,w]=[ax,ay,aw]=[x/w,y/w,1]都可以表示同一个二维点,所以单应性矩阵H也仅仅依赖尺度定义,单应性矩阵H有8个独立的自由度。我们通常使用w=1来归一化点,这样点具有唯一的图像坐标x和y。
下面的代码实现了对点进行归一化和转换成齐次坐标:
# coding=UTF-8
from PIL import Image
from numpy import *
from pylab import *
def make_homog(points):
'''
:param points:
:return:
'''
return vstack((points, ones((1, points.shape[1]))))
def normalize(points):
'''
在齐次坐标下进行归一化处理
:param points:
:return:
'''
for row in points:
row /= points[-1]
return points单应性矩阵可以通过对应点计算出来,一个完全的单应性矩阵有8个自由度,所以需要4个对应点对计算单应性矩阵,下面我们使用SVD算法找到H的最小二乘解:
def Hfrompoints(fp, tp):
'''
求解单应性矩阵,使fp映射到tp
:param fp:
:param tp:
:return:
'''
if fp.shape != tp.shape:
raise RuntimeError('number of points do not match!')
# 对点进行归一化
m = mean(fp[:2], axis=1)
maxstd = max(std(fp[:2], axis=1)) + 1e-9
C1 = diag([1/maxstd, 1/maxstd, 1])
C1[0][2] = -m[0] / maxstd
C1[1][2] = -m[0] / maxstd
fp = dot(C1, fp)
# 映射对应点
m = mean(tp[:2], axis=1)
maxstd = max(std(tp[:2], axis=1)) + 1e-9
C2 = diag([1 / maxstd, 1 / maxstd, 1])
C2[0][2] = -m[0] / maxstd
C2[1][2] = -m[0] / maxstd
tp = dot(C1, tp)
# 求解 H
nbr_correspondences = fp.shape[1]
A = zeros((2 * nbr_correspondences, 9))
for i in range(nbr_correspondences):
A[2 * i] = [-fp[0][i], -fp[1][i], -1, 0, 0, 0,
tp[0][i] * fp[0][i], tp[0][i] * fp[1][i], tp[0][i]]
A[2 * i + 1] = [0, 0, 0, -fp[0][i], -fp[1][i], -1,
tp[1][i] * fp[0][i], tp[1][i] * fp[1][i], tp[1][i]]
U, S, V = linalg.svd(A)
H = V[8].reshape((3, 3))
# 反归一化
H = dot(linalg.inv(C2), dot(H, C1))
# 返回归一化
return H / H[2, 2]
齐次坐标是在实际应用中非常有用的表达式,点的齐次坐标依赖其尺度定义,所以x=[x,y,w]=[ax,ay,aw]=[x/w,y/w,1]都可以表示同一个二维点,所以单应性矩阵H也仅仅依赖尺度定义,单应性矩阵H有8个独立的自由度。我们通常使用w=1来归一化点,这样点具有唯一的图像坐标x和y。
下面的代码实现了对点进行归一化和转换成齐次坐标:
# coding=UTF-8
from PIL import Image
from numpy import *
from pylab import *
def make_homog(points):
'''
:param points:
:return:
'''
return vstack((points, ones((1, points.shape[1]))))
def normalize(points):
'''
在齐次坐标下进行归一化处理
:param points:
:return:
'''
for row in points:
row /= points[-1]
return points单应性矩阵可以通过对应点计算出来,一个完全的单应性矩阵有8个自由度,所以需要4个对应点对计算单应性矩阵,下面我们使用SVD算法找到H的最小二乘解:
def Hfrompoints(fp, tp):
'''
求解单应性矩阵,使fp映射到tp
:param fp:
:param tp:
:return:
'''
if fp.shape != tp.shape:
raise RuntimeError('number of points do not match!')
# 对点进行归一化
m = mean(fp[:2], axis=1)
maxstd = max(std(fp[:2], axis=1)) + 1e-9
C1 = diag([1/maxstd, 1/maxstd, 1])
C1[0][2] = -m[0] / maxstd
C1[1][2] = -m[0] / maxstd
fp = dot(C1, fp)
# 映射对应点
m = mean(tp[:2], axis=1)
maxstd = max(std(tp[:2], axis=1)) + 1e-9
C2 = diag([1 / maxstd, 1 / maxstd, 1])
C2[0][2] = -m[0] / maxstd
C2[1][2] = -m[0] / maxstd
tp = dot(C1, tp)
# 求解 H
nbr_correspondences = fp.shape[1]
A = zeros((2 * nbr_correspondences, 9))
for i in range(nbr_correspondences):
A[2 * i] = [-fp[0][i], -fp[1][i], -1, 0, 0, 0,
tp[0][i] * fp[0][i], tp[0][i] * fp[1][i], tp[0][i]]
A[2 * i + 1] = [0, 0, 0, -fp[0][i], -fp[1][i], -1,
tp[1][i] * fp[0][i], tp[1][i] * fp[1][i], tp[1][i]]
U, S, V = linalg.svd(A)
H = V[8].reshape((3, 3))
# 反归一化
H = dot(linalg.inv(C2), dot(H, C1))
# 返回归一化
return H / H[2, 2]
相关文章推荐
- 【懒懒的计算机视觉笔记之Harris角点检测二】
- 【懒懒的计算机视觉笔记之SIFT角点检测】
- 【懒懒的计算机视觉笔记之Harris角点检测一】
- (一)图像坐标:我想和世界坐标谈谈(A) 【计算机视觉学习笔记--双目视觉几何框架系列】
- opencv计算机视觉学习笔记一
- 20170215.【计算机视觉学习笔记--双目视觉几何框架系列】
- (八)走向三维 【计算机视觉学习笔记--双目视觉几何框架系列】
- 张正友标定法 【计算机视觉学习笔记--双目视觉几何框架系列】
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时2
- 【Oencv2计算机视觉学习笔记(一)】QT5.3.1 与 OpenCV2.4.9 环境搭建
- 计算机视觉与图像处理学习笔记(三)opencv的基本数据类型与简单图像处理函数
- (二)图像坐标:我想和世界坐标谈谈(B) 【计算机视觉学习笔记--双目视觉的几何框架系列】
- 深度学习与计算机视觉[CS231N] 学习笔记(2.2):K-近邻算法(K-Nearest Neighbors)
- CS231n-深度学习与计算机视觉-笔记-Lecture7.3 迁移学习
- opencv计算机视觉学习笔记二
- 《计算机视觉:模型、学习和推理》自学笔记(一)-绪论
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时10
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时14&&15
- (三)张正友标定法 【计算机视觉学习笔记--双目视觉几何框架系列】
- 计算机视觉 学习笔记(入门篇 序)