在OpenCV中绘制平面的法向量

时间:2018-02-20 09:45:12

标签: opencv image-processing camera linear-algebra pose-estimation

我使用2D条形码识别3D空间中的平面,我想绘制相对于其中心的法线。

这是我用来计算正常

的代码
def compute_normal(camera, board, bounds, frame):
    extrinsics, ip, op = get_extrinsics(camera, frame, board, bounds)
    extrinsic = extrinsics[0]

    if not extrinsic: return [], None

    camera_transform = M_from_extrinsic(extrinsic)
    transformed_board = transform_board(board, camera_transform)

    # change this to be the corners of any board, not just 4-square

    p1 = transformed_board[3][:3]
    p2 = transformed_board[6][:3]
    p3 = transformed_board[8][:3]

    l1 = p2 - p1
    l2 = p3 - p1

    normal = np.cross(l1, l2)

    return normal, extrinsic

board只是一个3xN的对象点数组(所有内容都由solvePnP支持)。点p1,p2,p3是理想校准板的左上角,右上角和左下角。带圆圈的点是我为计算选择的点。其他几点是更多的角落,这些角落没有被考虑。

enter image description here

在我计算法线之后,这是我绘制它的方式。

normal, extrinsic = compute_normal(camera0, board0, [[0, 4]], im)

if len(normal):

    projected_center, jac0 = cv2.projectPoints(board_center, extrinsic.rvec, extrinsic.tvec, camera0.mtx, camera0.dist)
    projected_norm, jac1 = cv2.projectPoints(np.array([normal]), extrinsic.rvec, extrinsic.tvec, camera0.mtx, camera0.dist)

    origin = clean_image_points(projected_center.reshape(1, 2))[0]
    vec = clean_image_points(projected_norm.reshape(1, 2))[0]

    cv2.arrowedLine(im, origin, vec, (0, 255, 0), 5)

但是,我得到的结果看起来像这样

enter image description here

正如您所看到的,绿线指向应指向屏幕的某个方向,因为电路板或多或少地面向相机。

我可以确认计算extrinsics工作正常,因为我在其他几个地方使用它。我只是不确定正常的计算和绘图。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

本身不是答案,但您可以直接为自己的调试流输出输出吗?当你向右转(x轴否定)或者它似乎沿对角线镜像时(y和x值切换),你可能会注意到箭头向左移动的东西。