创建一个程序以在魔方图像上放置坐标系

问题描述 投票:0回答:1

我是一名学生,正在从事涉及图像处理的学校项目,我确实需要一些帮助。我是编程新手,尤其是 Python 和 OpenCV,我正在尝试完成一项特定任务。 我想编写一个程序,将 3D 坐标系放置在图像中魔方的一个角上。该系统的轴应与立方体的边缘对齐并形成直角。 随后,我需要提取相对于该坐标系的 XYZ 坐标以及图像上以像素为单位的 XY 坐标以进行校准

“我无法对齐坐标系,使其成直角且与立方体的边缘对齐。”

python opencv 3d coordinates coordinate-systems
1个回答
0
投票

为了实现将 3D 坐标系放置在图像中魔方的一角并将其与立方体边缘对齐的目标,您需要遵循使用 Python 和 OpenCV 的结构化方法。这涉及立方体的检测、其姿态的估计以及 3D 坐标系的可视化。以下是分步指南以及代码片段,可帮助您完成整个过程:

第1步:检测图像中的魔方

首先,您需要检测图像中的魔方,这涉及到识别魔方的角。这可以使用边缘检测和轮廓近似来实现:

import cv2
import numpy as np

# Load the image
image = cv2.imread('rubiks_cube.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# Find contours
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Iterate through contours and find the cube
for contour in contours:
    # Approximate the contour to a polygon
    epsilon = 0.02 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)

    # Check if the approximated polygon has 4 sides (potentially a cube face)
    if len(approx) == 4:
        cv2.drawContours(image, [approx], 0, (0, 255, 0), 3)

cv2.imshow('Detected Cube', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

第 2 步:估计魔方的姿势

使用检测到的角点,估计立方体的姿态以对齐 3D 坐标系。这涉及解决透视 n 点 (PnP) 问题:

# Define the 3D model points of the cube corners
object_points = np.array([
    [0, 0, 0],
    [1, 0, 0],
    [1, 1, 0],
    [0, 1, 0]
], dtype=np.float32)

# Get the 2D image points from the detected corners
image_points = np.array([point[0] for point in approx], dtype=np.float32)

# Camera matrix and distortion coefficients (assuming no distortion)
focal_length = 1
center = (image.shape[1] / 2, image.shape[0] / 2)
camera_matrix = np.array([
    [focal_length, 0, center[0]],
    [0, focal_length, center[1]],
    [0, 0, 1]
], dtype=np.float32)

dist_coeffs = np.zeros((4, 1))  # Assuming no lens distortion

# Solve PnP to get the rotation and translation vectors
_, rvecs, tvecs = cv2.solvePnP(object_points, image_points, camera_matrix, dist_coeffs)

# Project the 3D axes onto the image plane
axis = np.float32([[3, 0, 0], [0, 3, 0], [0, 0, 3]]).reshape(-1, 3)
imgpts, _ = cv2.projectPoints(axis, rvecs, tvecs, camera_matrix, dist_coeffs)

# Draw the 3D coordinate system
corner = tuple(image_points[0].ravel())
image = cv2.line(image, corner, tuple(imgpts[0].ravel()), (255, 0, 0), 5)  # X-axis (Red)
image = cv2.line(image, corner, tuple(imgpts[1].ravel()), (0, 255, 0), 5)  # Y-axis (Green)
image = cv2.line(image, corner, tuple(imgpts[2].ravel()), (0, 0, 255), 5)  # Z-axis (Blue)

cv2.imshow('Cube with Coordinate System', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

第3步:校准和坐标提取

要提取相对于该坐标系的 XYZ 坐标并将其转换为像素坐标,您可以按照以下步骤操作:

  • 校准:如果需要,校准您的相机以获得精确的内部参数。如果您计划将现实世界的测量准确地映射到像素值,这一点至关重要。
  • 坐标提取:使用旋转 (
    rvecs
    ) 和平移 (
    tvecs
    ) 向量将点从 3D 空间转换到图像平面。

结论

此工作流程提供了一种基本方法来检测魔方、估计其姿势以及可视化与其边缘对齐的 3D 坐标系。根据项目所需的复杂性和准确性,可能需要进一步的改进,例如更先进的立方体检测方法或精确的相机校准。此外,请确保您已使用 OpenCV 和图像处理任务所需的库正确设置环境。

© www.soinside.com 2019 - 2024. All rights reserved.