根据世界空间坐标和图像坐标估计点的位置

2024-05-15 03:12:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用8个aruco标记,opencv和python来检测棋盘。标记检测工作正常,但一旦一个球员移动,至少一个标记通常会被他们的手臂覆盖。由于大多数标记仍然可以被检测到,所以可以根据其他标记的位置来估计该点。为了说明我的设置,我链接了一张图片。Correct Marker Points

我第一次尝试预测一个缺失点是试图计算从世界到图像空间的未知转换矩阵。为了表示8个标记角位置,使用了世界空间坐标[1,0,0]、[1,50,0]、[1,75,0]、[1100,0]、[1,0100]、[1,0,50]、[1,75100]和[1100100]。因此,这些都是已知的,并由矩阵W表示。标记点的屏幕空间坐标由opencv计算并由矩阵S表示。为了便于讨论,假设没有检测到一个标记,需要对该点进行估计。然后为给定的7个点计算从W到S的变换矩阵(即求解X的W*X=S),并将世界空间坐标乘以X来估计缺失点。问题是X没有包含透视变换,因此错误地投射了一个估计点。为了说明这一点,第二张图片连接在所有点都被正确检测到的地方,但随后被投影矩阵X投影。 Incorrect Marker Points

python代码的一个快速片段,显示了如何计算X和投影点:

ids = [81,277,939,275,683,677,335,981]

corner_world_coord = {
    683: [1,0,0],
    275: [1,50,0],
    939: [1,75,0],
    81: [1,100,0],
    335: [1,0,100],
    677: [1,50,100],
    277: [1,75,100],
    981: [1,100,100]
}

W = [corner_world_coord[i] for i in ids]
S = [aruco_corners[i] for i in ids]

X, res, _, _ = np.linalg.lstsq(W,S)

estimate = np.zeros(len(ids))

for idx, corner in enumerate(W):
    estimate[idx] = np.dot(corner,X)

X的最小平方误差计算的残差总是等于0。因此,我的问题是,有没有一种方法来计算一个缺失点的屏幕坐标,给定世界空间和其他多个点的屏幕空间坐标?在


Tags: in标记idsfor屏幕np世界空间
1条回答
网友
1楼 · 发布于 2024-05-15 03:12:48

我在以下问题下找到了解决办法: How to draw a Perspective-Correct Grid in 2D

在这种情况下,您的图像世界和图像空间需要4个非共线二维点。一、 e.从世界坐标中去掉一个,得到[0,0], [50,0]、[75,0]、[100,0]、[0100]、[50100]、[75100]和[100100]。非共线可能不是正确的术语,但它的意思是,它们需要创建一个四边形,最多允许2个点位于同一直线上。这4个点的x坐标,我们称之为x1…x4和y坐标y1…y4。对应的图像空间点的坐标我们称为x1p…x4p和y1p…y4p(p代表素数)。透视正确转换矩阵的计算如下所示:

def compute_proj_matrix(self, world_points, image_points):
    # compute A * C = B 
    # A is the following 8x8 Matrix:
    # x1   y1     1     0   0    0   -x1*x1'  -y1*x1'
    # 0    0     0    x1   y1   1   -x1*y1'  -y1*y1'
    # x2   y2     1     0   0    0   -x2*x2'  -y2*x2'
    # 0    0     0    x2   y2   1   -x2*y2'  -y2*y2'
    # x3   y3     1     0   0    0   -x3*x3'  -y3*x3'
    # 0    0     0    x3   y3   1   -x3*y3'  -y3*y3'
    # x4   y4     1     0   0    0   -x4*x4'  -y4*x4'
    # 0    0     0    x4   y4   1   -x4*y4'  -y4*y4'
    # B = [x1p,y1p,x2p,y2p,x3p,y3p,x4p,y4p]
    x1,x2,x3,x4 = world_points[:,0]
    y1,y2,y3,y4 = world_points[:,1]
    x1p,x2p,x3p,x4p = image_points[:,0]
    y1p,y2p,y3p,y4p = image_points[:,1]
    A = np.array([
        [x1,y1, 1, 0, 0, 0, -x1*x1p, -y1*x1p],
        [ 0, 0, 0,x1,y1, 1, -x1*y1p, -y1*y1p],
        [x2,y2, 1, 0, 0, 0, -x2*x2p, -y2*x2p],
        [ 0, 0, 0,x2,y2, 1, -x2*y2p, -y2*y2p],
        [x3,y3, 1, 0, 0, 0, -x3*x3p, -y3*x3p],
        [ 0, 0, 0,x3,y3, 1, -x3*y3p, -y3*y3p],
        [x4,y4, 1, 0, 0, 0, -x4*x4p, -y4*x4p],
        [ 0, 0, 0,x4,y4, 1, -x4*y4p, -y4*y4p]])
    B = np.array([x1p,y1p,x2p,y2p,x3p,y3p,x4p,y4p])
    return np.linalg.solve(A,B)

新(在上述情况下,缺失)点的映射通过以下方式完成:

^{pr2}$

为什么和如何工作可以在上面的问题中找到最好的答案,因为坦率地说,我不了解自己,只是很高兴找到了解决办法。在

相关问题 更多 >

    热门问题