做保密处理或者坐标系转换的时候经常会用到关于空间配准的问题,那么如何根据已知点对求得坐标转换的参数是一个值得研究的问题。这里用到的编程技巧不多,关键是要用到线性代数和数值分析的知识。纵观当前地图坐标保密处理或者坐标系转换的实例,其无外乎采用旋转、平移、拉伸等方式,于是数值的计算无外乎于解n个n元一次方程组,最后通过误差分析进行拟合。
下面就是一个形如 x' = Ax + by +C; y' = Dx + Ey +F 的六参数仿射变换的数值解法,采用Python2语言。
__author__ = 'Lee' # -*- coding: utf-8 -*- def affine_fit(from_pts, to_pts): q = from_pts p = to_pts if len(q) != len(p) or len(q) < 1: print "原始点和目标点的个数必须相同." return False dim = len(q[0]) # 维度 if len(q) < dim: print "点数小于维度." return False # 新建一个空的 维度 x (维度+1) 矩阵 并填满 c = [[0.0 for a in range(dim)] for i in range(dim+1)] for j in range(dim): for k in range(dim+1): for i in range(len(q)): qt = list(q[i]) + [1] c[k][j] += qt[k] * p[i][j] # 新建一个空的 (维度+1) x (维度+1) 矩阵 并填满 Q = [[0.0 for a in range(dim)] + [0] for i in range(dim+1)] for qi in q: qt = list(qi) + [1] for i in range(dim+1): for j in range(dim+1): Q[i][j] += qt[i] * qt[j] # 判断原始点和目标点是否共线,共线则无解. 耗时计算,如果追求效率可以不用。 # 其实就是解n个三元一次方程组 def gauss_jordan(m, eps=1.0/(10**10)): (h, w) = (len(m), len(m[0])) for y in range(0, h): maxrow = y for y2 in range(y+1, h): if abs(m[y2][y]) > abs(m[maxrow][y]): maxrow = y2 (m[y], m[maxrow]) = (m[maxrow], m[y]) if abs(m[y][y]) <= eps: return False for y2 in range(y+1, h): c = m[y2][y] / m[y][y] for x in range(y, w): m[y2][x] -= m[y][x] * c for y in range(h-1, 0-1, -1): c = m[y][y] for y2 in range(0, y): for x in range(w-1, y-1, -1): m[y2][x] -= m[y][x] * m[y2][y] / c m[y][y] /= c for x in range(h, w): m[y][x] /= c return True M = [Q[i] + c[i] for i in range(dim+1)] if not gauss_jordan(M): print "错误,原始点和目标点也许是共线的." return False class transformation: """对象化仿射变换.""" def To_Str(self): res = "" for j in range(dim): str = "x%d' = " % j for i in range(dim): str +="x%d * %f + " % (i, M[i][j+dim+1]) str += "%f" % M[dim][j+dim+1] res += str + "\n" return res def transform(self, pt): res = [0.0 for a in range(dim)] for j in range(dim): for i in range(dim): res[j] += pt[i] * M[i][j+dim+1] res[j] += M[dim][j+dim+1] return res return transformation() def test(): from_pt = ((38671803.6437, 2578831.9242), (38407102.8445, 2504239.2774), (38122268.3963, 2358570.38514), (38126455.4595, 2346827.2602), (38177232.2601, 2398763.77833), (38423567.3485, 2571733.9203), (38636876.4495, 2543442.3694), (38754169.8762, 2662401.86536), (38410773.8815, 2558886.6518), (38668962.0430, 2578747.6349)) # 输入点坐标对 to_pt = ((38671804.6165, 2578831.1944), (38407104.0875, 2504239.1898), (38122269.2925, 2358571.57626), (38126456.5675, 2346826.27022), (38177232.3973, 2398762.11714), (38423565.7744, 2571735.2278), (38636873.6217, 2543440.7216), (38754168.8662, 2662401.86101), (38410774.5621, 2558886.0921), (38668962.5493, 2578746.94)) # 输出点坐标对 trn = affine_fit(from_pt, to_pt) if trn: print "转换公式:" print trn.To_Str() err = 0.0 for i in range(len(from_pt)): fp = from_pt[i] tp = to_pt[i] t = trn.Transform(fp) print ("%s => %s ~= %s" % (fp, tuple(t), tp)) err += ((tp[0] - t[0])**2 + (tp[1] - t[1])**2)**0.5 print "拟合误差 = %f" % err if __name__ == "__main__": test()
相关推荐
**图像仿射变换** 在计算机视觉领域,图像处理是一个至关重要的环节,而OpenCV(开源计算机视觉库)是实现各种图像处理技术的强大工具。本文将深入探讨如何利用OpenCV进行图像的仿射变换,其中包括图像的旋转。仿射...
在本压缩包中,包含的“仿射变换”源代码很可能是用一种编程语言(如C++, Python或Java)实现的,以帮助初学者理解和应用这一理论。这些源代码通常会包含以下几个核心部分: 1. **定义矩阵**:在代码中,会定义一个...
2. **构建变换矩阵**:根据需求设置拉伸、旋转、平移等参数,构建2x3的仿射变换矩阵。 3. **定义目标尺寸**:根据变换结果,确定输出图像的尺寸。 4. **调用`cv2.warpAffine()`**:使用前面的参数调用函数,得到变换...
本篇文章将详细探讨如何使用Python和OpenCV实现仿射变换,特别是坐标变换的效果。 首先,了解仿射变换的基本概念。仿射变换是一种线性变换,它可以将一个平面内的图形映射到另一个平面上,同时保持平行线的关系不变...
在OpenCV-Python中进行图像处理时,仿射变换是一个常用且重要的技术。仿射变换是一种线性映射,它可以保持图像的平行性,但不保证比例一致性。这个压缩包文件"OpenCV-Python仿射变换开发中遇到的坑.rar"很可能包含了...
OpenCV3提供了 `getAffineTransform()` 函数来计算仿射变换矩阵。该函数接受三个点的坐标作为输入,即源图像上的三个点和目标图像上对应的三个点,然后计算出能够将源图像转换为目标图像的仿射变换矩阵。 ```cpp cv...
接着,使用`cv2.warpAffine()`函数将计算得到的仿射变换矩阵应用于图像: ```python dst = cv2.warpAffine(src, M, (cols, rows)) ``` - `src`: 原始图像。 - `M`: 仿射变换矩阵。 - `(cols, rows)`: 输出图像的尺寸...
# 计算仿射变换矩阵 matrix = np.linalg.solve(points_src[:, np.newaxis, :], points_dst[:, np.newaxis, :]).squeeze() # 应用仿射变换 def affine_algorithm(image, matrix): return affine_transform(image, ...
这个函数接受三个参数:原始图像、2x3的仿射变换矩阵以及输出图像的尺寸。在上述示例中,`(w, h)`是原始图像的宽度和高度,`borderValue`参数用于指定边界像素的填充值,这里设为125。 在缩放过程中,可能出现的...
本文将详细介绍如何使用OpenCV实现图像的仿射变换,特别是平移功能。仿射变换是一种线性几何变换,它保持了直线的平行性和角度,适用于图像的平移、缩放和旋转等操作。 首先,我们需要了解平移的概念。在二维几何中...
该函数用于生成旋转仿射变换矩阵,它接受三个参数: 1. `center`:旋转中心点坐标,表示为(x,y)的元组形式,如果是(0,0)则以图像的左上角为旋转中心。 2. `angle`:旋转角度,以度为单位,正值为逆时针旋转,负值为...
这些操作在坐标转换的参数计算中至关重要,因为坐标转换问题往往可以转化为线性代数问题,通过矩阵运算来解决。 在实际应用中,用户可以通过这个项目快速地进行坐标转换,无论是四参数还是七参数,都只需要输入必要...
例如,IFS吸引子图像仿射变换的参数变换法就是利用IFS理论对图像进行处理,通过改变IFS中仿射变换的参数,可以创建出具有不同细节和复杂度的自相似图像。这种方法可以用于艺术创作,创造出独特的分形艺术作品,也...
为了实现这个过程,首先需要定义一个损失函数,如归一化的互信息或均方误差,然后计算这个函数关于仿射变换参数的梯度。接着,使用梯度下降算法更新参数,可能需要设定学习率(控制每次更新的步长)和停止条件(如...
在进行仿射变换之前,需要确定变换矩阵的参数,这些参数通常根据变换前后的控制点来计算得出。 由于技术原因,部分文字可能存在OCR扫描错误或遗漏,例如本部分内容中“汾射变换”和“访射变换”可能是“仿射变换”...
一旦得到倾斜角度,可以通过仿射变换(`cv2.getRotationMatrix2D`和`cv2.warpAffine`函数)来旋转图像,使其水平对齐。 在实际操作中,可能还需要考虑一些优化策略,比如选择合适的阈值来控制边缘检测和Hough变换的...
4. 仿射变换:除了基本的平移、旋转和缩放,仿射变换还能保持图像的线性特性,如倾斜、扭曲等,通常涉及`getAffineTransform()`和`warpAffine()`函数。 5. 镜像翻转:水平或垂直翻转图像,OpenCV提供了`flip()`函数...
然后,我们使用这些点来计算仿射变换矩阵。最后,`cv2.warpAffine()`函数将这个变换应用到原始图像上,生成一个新的变形图像。 值得注意的是,`cv2.warpAffine()`函数需要一个二维的输出尺寸参数,即`(img.shape[1]...
在OpenCV中,几何变换是图像处理的重要组成部分,它允许我们对图像进行各种操作,如缩放、平移、旋转、仿射变换和透视变换。这些变换在图像分析、识别和增强等领域有着广泛的应用。 1. **扩展缩放**: 使用`cv2....
2. **几何变换模块**:在确定了文本的弯曲程度后,这一模块会运用数学模型,如透视变换或仿射变换,来对图像进行校正。这种变换需要精确计算出适当的变换矩阵,确保校正后的文本保持清晰且无失真。 3. **优化模块**...