c++opencvaruco

Assertion failed error when trying to detect Aruco code via OpenCV 4.8 and 4.10


I have been grappling with this issue the past few days. I am a beginner C++/OpenCV developer trying to write a small program to learn Aruco codes. I keep getting the assertion failure

 (`OpenCV(4.8.1) Error: Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0)) in create, file /home/ci/opencv/modules/core/src/matrix_wrap.cpp, line 1393`)

In both OpenCV 4.8.1 and 4.10.0-dev, when I try to detect a Aruco marker. This is the command used to build OpenCV for both versions:

$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
$ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/home/raj/.local -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
$ make -j$(nproc) && make install

Code:

#include <opencv2/opencv.hpp>
#include <opencv2/objdetect/aruco_detector.hpp>
#include <iostream>

#define DICT cv::aruco::DICT_6X6_100

cv::Mat generateMarker(int id) {
    cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(DICT);
    cv::Mat marker;
    cv::aruco::generateImageMarker(dictionary, 0, 200, marker, 1);
    return marker;
}

//for OpenCV version > 4.5
int main() {
    // read image
    cv::Mat imgCopy, img = generateMarker(10); // cv::imread("/tmp/sk2.png"); 

    std::cout << "Converting to Gray scale! " << std::endl;
    // convert to Gray scale before detection
    int incn = img.channels();
    if (incn == 3 || incn == 4)
        cvtColor(img, imgCopy, cv::COLOR_BGR2GRAY);
    else if (incn == 1)
        img.copyTo(imgCopy);
    else {
        std::cout << "Unsupported image format" << std::endl;
        img.release();
        return -1;
    }

    // detect aruco markers:
    cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(DICT);
    cv::aruco::ArucoDetector detector(dictionary);

    std::vector<int> markerIds;
    std::vector<std::vector<cv::Point2f>> markerCorners;

    try {
        detector.detectMarkers(imgCopy, markerIds, markerCorners);
    } catch (std::exception& e) {
        std::cout << "Exception: " << e.what() << std::endl;
        return -1;
    }

    std::cout << "Detected markers: " << markerIds.size() << std::endl;
    for (int i = 0; i < markerIds.size(); i++) {
        std::cout << "Marker ID: " << markerIds[i] << std::endl;
    }

    // draw detected markers
    if (markerIds.size() > 0) cv::aruco::drawDetectedMarkers(imgCopy, markerCorners, markerIds);

    cv::imshow("Image", imgCopy);

    // wait for a key press to exit
    cv::waitKey(0);
    cv::destroyAllWindows();
    img.release();
    imgCopy.release();

    return 0;
}

The surprising thing is that the below code works fine with OpenCV 4.5.1. The command used to build OpenCV 4.5 is same as that for 4.8 and 4.10 above. And the code used to determine the marker:

int main() {
    std::cout << "OpenCV version: " << CV_VERSION << std::endl;

    // read image
    cv::Mat imgCopy, img = cv::imread("/tmp/sk2.png");

    cvtColor(img, imgCopy, cv::COLOR_BGR2GRAY);
    std::vector<int> ids;
    std::vector<std::vector<cv::Point2f>> corners;
    cv::Ptr<cv::aruco::Dictionary> dictionary =
        cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);

    cv::aruco::detectMarkers(imgCopy, dictionary, corners, ids);
    if (ids.size() > 0) {
        cv::aruco::drawDetectedMarkers(imgCopy, corners, ids);
    }

    cv::imshow("Image", imgCopy);

    cv::waitKey(0);
    cv::destroyAllWindows();
    img.release();
    imgCopy.release();
}

sk2.png


Solution

  • try switching the order (your code worked on 4.10.0):

    detector.detectMarkers(imgCopy, markerCorners, markerIds);

    the previous version appears to be marked deprecated -- the parameter types outputArray aren't very strict and the runtime is left w/ confusing asserts