OPENCV ARUCO摄像机校准无法正常工作。

发布于 2025-01-21 18:54:54 字数 3049 浏览 0 评论 0原文

我正在尝试使用OpenCV校准相机,但是它一直返回此错误:

error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv_contrib\modules\aruco\src\aruco.cpp:1769: error: (-215:Assertion failed) nMarkersInThisFrame > 0 in function 'cv::aruco::calibrateCameraAruco'

这是它的代码,除了“ #Actual Calibration”的零件之外,它的每个部分都可以使用

def calibrate_aruco(num_markers_row, num_markers_column, side_length, marker_separation, marker_separation_x):
    """Calibrates Camera Using ArUco Tags"""
    
    aruco_dict = aruco.Dictionary_get(aruco.DICT_5X5_250)
    arucoParams = aruco.DetectorParameters_create()
    
    tag_corners = []
    sep_array_y = [0, marker_separation + side_length, marker_separation + side_length, 0]
    sep_array_x = [0, 0, marker_separation_x + side_length, marker_separation_x + side_length]
    for i in range(num_markers_column*num_markers_row):
        top_left = np.array([sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        top_right = np.array([side_length + sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        bottom_right = np.array([side_length + sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        bottom_left = np.array([sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        tag_corners.append(np.array([top_left, top_right, bottom_right, bottom_left]))
    
    board_ids = np.array( [[0],[1],[2],[3]], dtype=np.int32)
    
    board = aruco.Board_create(tag_corners, aruco_dict, board_ids)

    # Find the ArUco markers inside target image
    image = cv2.imread(r"D:\Downloads\target_1.png")
    img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #cv2.imshow("obama", img_gray)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    corners, ids, rejected = aruco.detectMarkers(
        img_gray, 
        aruco_dict, 
        parameters=arucoParams
    )
    
    # Actual calibration
    ret, mtx, dist, rvecs, tvecs = aruco.calibrateCameraAruco(
        corners, 
        ids, 
        num_markers_row*num_markers_column, 
        board, 
        img_gray.shape, 
        None,
        None
    )
    return ret, mtx, dist, rvecs, tvecs

以下输入来限制此方法:

import cv2
import cv2.aruco as aruco
import numpy as np

num_markers_row = 2 #number of rows
num_markers_column = 2 #numbers of columns

side_length = 5 #side length of ar tags in cm

dist_to_circle = 3.75 #distance between the y coordinate of ar tag and the y coordinate of circle
dist_between_centers = 2 * dist_to_circle
marker_separation = dist_between_centers - side_length

dist_to_circle_x = 10
dist_between_centers_x = 2 * dist_to_circle_x
marker_separation_x = dist_between_centers_x - side_length

print(marker_separation)
print(marker_separation_x)

我得到了大多数代码来自这里;我编辑的唯一部分是将Aruco标签从遵循网格板格式更改为遵循通用板格式。我还更改了程序,以将校准级函数提供单个框架而不是多个函数。我要校准的图像如下: ”在此处输入图像说明”

I'm trying to calibrate my camera with OpenCV, but it keeps returning this error:

error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv_contrib\modules\aruco\src\aruco.cpp:1769: error: (-215:Assertion failed) nMarkersInThisFrame > 0 in function 'cv::aruco::calibrateCameraAruco'

This is the code for it, every part of it works besides the part under "#Actual Calibration"

def calibrate_aruco(num_markers_row, num_markers_column, side_length, marker_separation, marker_separation_x):
    """Calibrates Camera Using ArUco Tags"""
    
    aruco_dict = aruco.Dictionary_get(aruco.DICT_5X5_250)
    arucoParams = aruco.DetectorParameters_create()
    
    tag_corners = []
    sep_array_y = [0, marker_separation + side_length, marker_separation + side_length, 0]
    sep_array_x = [0, 0, marker_separation_x + side_length, marker_separation_x + side_length]
    for i in range(num_markers_column*num_markers_row):
        top_left = np.array([sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        top_right = np.array([side_length + sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        bottom_right = np.array([side_length + sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        bottom_left = np.array([sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        tag_corners.append(np.array([top_left, top_right, bottom_right, bottom_left]))
    
    board_ids = np.array( [[0],[1],[2],[3]], dtype=np.int32)
    
    board = aruco.Board_create(tag_corners, aruco_dict, board_ids)

    # Find the ArUco markers inside target image
    image = cv2.imread(r"D:\Downloads\target_1.png")
    img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #cv2.imshow("obama", img_gray)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    corners, ids, rejected = aruco.detectMarkers(
        img_gray, 
        aruco_dict, 
        parameters=arucoParams
    )
    
    # Actual calibration
    ret, mtx, dist, rvecs, tvecs = aruco.calibrateCameraAruco(
        corners, 
        ids, 
        num_markers_row*num_markers_column, 
        board, 
        img_gray.shape, 
        None,
        None
    )
    return ret, mtx, dist, rvecs, tvecs

I prefaced this method with the following inputs:

import cv2
import cv2.aruco as aruco
import numpy as np

num_markers_row = 2 #number of rows
num_markers_column = 2 #numbers of columns

side_length = 5 #side length of ar tags in cm

dist_to_circle = 3.75 #distance between the y coordinate of ar tag and the y coordinate of circle
dist_between_centers = 2 * dist_to_circle
marker_separation = dist_between_centers - side_length

dist_to_circle_x = 10
dist_between_centers_x = 2 * dist_to_circle_x
marker_separation_x = dist_between_centers_x - side_length

print(marker_separation)
print(marker_separation_x)

I got most of the code from here; the only part I edited was changing the ArUco tags from following a GridBoard format to following a general board format. I also changed the program to feed the CalibrateCameraAruco function a single frame instead of multiple. The image I'm using to calibrate is the following:enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

新人笑 2025-01-28 18:54:54

我通过馈送calibratecameraaruco功能多个帧而不是单个图像来解决此问题。完整代码如下:

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 16 12:26:08 2022

ArUco OpenCV Calibration
Only needs to be ran once
Run calibration only after Astrobee is at Target 1

@author: hudso
"""
import cv2
import cv2.aruco as aruco
import numpy as np
import glob
import os

def create_ArUco_board_format():
    """Defines constants and the general format of the ArUco Tags"""
    
    #These are the only changable variables
    num_markers_row = 2 #number of rows
    num_markers_column = 2 #numbers of columns
    side_length = 5 #side length of ar tags in cm
    
    #Calculates the marker separation as if in a grid
    dist_to_circle = 3.75
    dist_between_centers = 2 * dist_to_circle
    marker_separation = dist_between_centers - side_length
    
    dist_to_circle_x = 10
    dist_between_centers_x = 2 * dist_to_circle_x
    marker_separation_x = dist_between_centers_x - side_length
    
    #Downloads ArUco 5x5 250 Tag Dictionary
    aruco_dict = aruco.Dictionary_get(aruco.DICT_5X5_250)
    
    #Creates custom ArUco Board type object "board"
    tag_corners = []
    sep_array_y = [0, marker_separation + side_length, marker_separation + side_length, 0]
    sep_array_x = [0, 0, marker_separation_x + side_length, marker_separation_x + side_length]
    for i in range(num_markers_column*num_markers_row):
        top_left = np.array([sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        top_right = np.array([side_length + sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        bottom_right = np.array([side_length + sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        bottom_left = np.array([sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        tag_corners.append(np.array([top_left, top_right, bottom_right, bottom_left]))
    
    #Assigns the respective "board_ids" of the ArUco tags
    board_ids = np.array([[0],[1],[2],[3]], dtype=np.int32)
    
    #Creates board
    board = aruco.Board_create(tag_corners, aruco_dict, board_ids)
    
    return board, aruco_dict
    
def calibrate_aruco(board, aruco_dict):
    """Calibrates Camera Using ArUco Tags"""
    
    #Search through directory of Calibration Images
    cwd = os.getcwd()
    path = r"\Calibration_Images"
    os.chdir(cwd + path)
    files = glob.glob('*.{}'.format("jpg"))
    
    arucoParams = aruco.DetectorParameters_create()
    
    #Iterate over each calibration image and find markers
    all_corners = np.array([])
    all_ids = np.array([])
    num_detected_markers = []
    for file in files:
        #Open File
        image = cv2.imread(file)
        img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        cv2.imshow("obama", img_gray)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        
        #Detect markers
        corners, ids, rejected = aruco.detectMarkers(
            img_gray, 
            aruco_dict, 
            parameters=arucoParams
        )
        
        #Append marker data
        if np.size(all_corners) == 0:
            all_corners = corners
            all_ids = ids
        else:
            all_corners = np.append(all_corners, corners, axis=0)
            all_ids = np.append(all_ids, ids, axis=0)
        num_detected_markers.append(len(ids))
        
    num_detected_markers = np.array(num_detected_markers)

    #Uses markers to calibrate camera
    ret, mtx, dist, rvecs, tvecs = aruco.calibrateCameraAruco(
        all_corners, 
        all_ids, 
        num_detected_markers, 
        board, 
        img_gray.shape, 
        None, 
        None 
    )
    return ret, mtx, dist, rvecs, tvecs

#The actual execution of the methods
board, aruco_dict = create_ArUco_board_format()
ret, mtx, dist, rvecs, tvecs = calibrate_aruco(board, aruco_dict)
print(mtx) #Camera Matrix
print(dist) #Distortion Coefficients

I managed to fix this issue by feeding the calibrateCameraAruco function multiple frames instead of a single image. The full code is below:

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 16 12:26:08 2022

ArUco OpenCV Calibration
Only needs to be ran once
Run calibration only after Astrobee is at Target 1

@author: hudso
"""
import cv2
import cv2.aruco as aruco
import numpy as np
import glob
import os

def create_ArUco_board_format():
    """Defines constants and the general format of the ArUco Tags"""
    
    #These are the only changable variables
    num_markers_row = 2 #number of rows
    num_markers_column = 2 #numbers of columns
    side_length = 5 #side length of ar tags in cm
    
    #Calculates the marker separation as if in a grid
    dist_to_circle = 3.75
    dist_between_centers = 2 * dist_to_circle
    marker_separation = dist_between_centers - side_length
    
    dist_to_circle_x = 10
    dist_between_centers_x = 2 * dist_to_circle_x
    marker_separation_x = dist_between_centers_x - side_length
    
    #Downloads ArUco 5x5 250 Tag Dictionary
    aruco_dict = aruco.Dictionary_get(aruco.DICT_5X5_250)
    
    #Creates custom ArUco Board type object "board"
    tag_corners = []
    sep_array_y = [0, marker_separation + side_length, marker_separation + side_length, 0]
    sep_array_x = [0, 0, marker_separation_x + side_length, marker_separation_x + side_length]
    for i in range(num_markers_column*num_markers_row):
        top_left = np.array([sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        top_right = np.array([side_length + sep_array_x[i], side_length + sep_array_y[i], 0], dtype = np.float32)
        bottom_right = np.array([side_length + sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        bottom_left = np.array([sep_array_x[i], sep_array_y[i], 0], dtype = np.float32)
        tag_corners.append(np.array([top_left, top_right, bottom_right, bottom_left]))
    
    #Assigns the respective "board_ids" of the ArUco tags
    board_ids = np.array([[0],[1],[2],[3]], dtype=np.int32)
    
    #Creates board
    board = aruco.Board_create(tag_corners, aruco_dict, board_ids)
    
    return board, aruco_dict
    
def calibrate_aruco(board, aruco_dict):
    """Calibrates Camera Using ArUco Tags"""
    
    #Search through directory of Calibration Images
    cwd = os.getcwd()
    path = r"\Calibration_Images"
    os.chdir(cwd + path)
    files = glob.glob('*.{}'.format("jpg"))
    
    arucoParams = aruco.DetectorParameters_create()
    
    #Iterate over each calibration image and find markers
    all_corners = np.array([])
    all_ids = np.array([])
    num_detected_markers = []
    for file in files:
        #Open File
        image = cv2.imread(file)
        img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        cv2.imshow("obama", img_gray)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        
        #Detect markers
        corners, ids, rejected = aruco.detectMarkers(
            img_gray, 
            aruco_dict, 
            parameters=arucoParams
        )
        
        #Append marker data
        if np.size(all_corners) == 0:
            all_corners = corners
            all_ids = ids
        else:
            all_corners = np.append(all_corners, corners, axis=0)
            all_ids = np.append(all_ids, ids, axis=0)
        num_detected_markers.append(len(ids))
        
    num_detected_markers = np.array(num_detected_markers)

    #Uses markers to calibrate camera
    ret, mtx, dist, rvecs, tvecs = aruco.calibrateCameraAruco(
        all_corners, 
        all_ids, 
        num_detected_markers, 
        board, 
        img_gray.shape, 
        None, 
        None 
    )
    return ret, mtx, dist, rvecs, tvecs

#The actual execution of the methods
board, aruco_dict = create_ArUco_board_format()
ret, mtx, dist, rvecs, tvecs = calibrate_aruco(board, aruco_dict)
print(mtx) #Camera Matrix
print(dist) #Distortion Coefficients
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文