用于小组2D点的简单配准算法

时间:2016-01-04 22:20:45

标签: opencv 2d registration point point-clouds

我试图找到一个简单的算法来找到两组2D点之间的对应关系(注册)。一组包含我想要找到的对象的模板,第二组主要包含属于感兴趣对象的点,但它可能是嘈杂的(缺少点以及不属于该对象的附加点) 。两组在2D中包含大约40个点。第二组是第一组的单应性(平移,旋转和透视变换)。

我有兴趣找到一个注册算法,以获得点对应关系。我将使用此信息来查找两组之间的转换(所有这些都在OpenCV中)。

任何人都可以建议一个可以完成这项工作的算法,库或一小段代码吗?因为我正在处理小套装,所以不必进行超级优化。目前,我的方法是类似RANSAC的算法:

  1. 从第1组和第2组中选择4个随机点。
  2. 计算变换矩阵H(使用openCV getPerspective())
  3. 使用H扭曲第一组点并测试它们如何与第二组点对齐
  4. 重复1-3次,并根据某个度量(例如,平方和)选择最佳变换。
  5. 有什么想法吗?感谢您的投入。

3 个答案:

答案 0 :(得分:0)

您可以使用cv::findHomography。这是围绕cv::getPerspectiveTransform的基于RANSAC的方法。

auto H = cv::findHomography(srcPoints, dstPoints, CV_RANSAC,3);

其中3是重投影阈值。

答案 1 :(得分:0)

解决问题的一种传统方法是在没有匹配的配对信息时使用点集注册方法。点集注册与您正在讨论的方法类似。您可以找到matlab实现here

由于

答案 2 :(得分:0)

使用 python,您可以使用 Open3D 库,在 Anaconda 中安装非常容易。为了您的目的,ICP 应该可以正常工作,因此我们将使用经典 ICP,它在每次迭代中最小化最近点之间的点对点距离。这是注册 2 个云的代码:

import numpy as np
import open3d as o3d

# Parameters:
initial_T = np.identity(4) # Initial transformation for ICP

distance = 0.1 # The threshold distance used for searching correspondences
(closest points between clouds). I'm setting it to 10 cm.

# Read your point clouds:
source = o3d.io.read_point_cloud("point_cloud_1.xyz") 
target = o3d.io.read_point_cloud("point_cloud_0.xyz")

# Define the type of registration:
type = o3d.pipelines.registration.TransformationEstimationPointToPoint(False)
# "False" means rigid transformation, scale = 1

# Define the number of iterations (I'll use 100):
iterations = o3d.pipelines.registration.ICPConvergenceCriteria(max_iteration = 100)

# Do the registration:
result = o3d.pipelines.registration.registration_icp(source, target, distance, initial_T, type, iterations)

result 是一个包含 4 个东西的类:转换 T(4x4)、2 个 metrict(rmse 和适应度)和对应集。

enter image description here

访问转换:

enter image description here

我经常将它与从地面激光扫描仪 (TLS) 和机器人 (Velodiny LIDAR) 获得的 3D 云一起使用。

使用 MATLAB: 我们将再次使用点对点 ICP,因为您的数据是 2D 的。这是在三角形内随机生成两个点云的最小示例:

% Triangle vértices:
V1 = [-20, 0; -10, 10; 0, 0];
V2 = [-10, 0; 0, 10; 10, 0];
% Create clouds and show pair:
points = 5000
N1 = criar_nuvem_triangulo(V1,points);
N2 = criar_nuvem_triangulo(V2,points);
pcshowpair(N1,N2)

% Registrate pair N1->N2 and show:
[T,N1_tranformed,RMSE]=pcregistericp(N1,N2,'Metric','pointToPoint','MaxIterations',100);
pcshowpair(N1_tranformed,N2)

“criar_nuvem_triangulo”是一个在三角形内生成随机点云的函数:

function [cloud] = criar_nuvem_triangulo(V,N)
% Function wich creates 2D point clouds in triangle format using random
% points
% Parameters: V = Triangle vertices (3x2 Matrix)| N = Number of points
t = sqrt(rand(N, 1)); 
s = rand(N, 1);
P = (1 - t) * V(1, :) + bsxfun(@times, ((1 - s) * V(2, :) + s * V(3, :)), t);
points = [P,zeros(N,1)]; 
cloud = pointCloud(points)
end

结果: enter image description here