diff --git a/skimage/transform/_geometric.py b/skimage/transform/_geometric.py index e658d23e..cd9d9487 100644 --- a/skimage/transform/_geometric.py +++ b/skimage/transform/_geometric.py @@ -10,6 +10,54 @@ from ..exposure import rescale_intensity from ._warps_cy import _warp_fast +def _center_and_normalize_points(points): + """Center and normalize image points. + + The points are transformed in a two-step procedure that is expressed + as a transformation matrix. The matrix of the resulting points is usually + better conditioned than the matrix of the original points. + + Center the image points, such that the new coordinate system has its + origin at the centroid of the image points. + + Normalize the image points, such that the mean distance from the points + to the coordinate system is sqrt(2). + + Parameters + ---------- + points : (N, 2) array + The coordinates of the image points. + + Returns + ------- + matrix : (3, 3) array + The transformation matrix to obtain the new points. + new_points : (N, 2) array + The transformed image points. + + """ + + centroid = np.mean(points, axis=0) + + rms = math.sqrt(np.sum((points - centroid) ** 2) / points.shape[0]) + + norm_factor = math.sqrt(2) / rms + + matrix = np.array([[norm_factor, 0, -norm_factor * centroid[0]], + [0, norm_factor, -norm_factor * centroid[1]], + [0, 0, 1]]) + + pointsh = np.row_stack([points.T, np.ones((points.shape[0]),)]) + + new_pointsh = np.dot(matrix, pointsh).T + + new_points = new_pointsh[:, :2] + new_points[:, 0] /= new_pointsh[:, 2] + new_points[:, 1] /= new_pointsh[:, 2] + + return matrix, new_points + + class GeometricTransform(object): """Perform geometric transformations on a set of coordinates.