Detecting charucoboard using objective c++ on iOS

I am having difficulties in detecting charuco board. I am working on a 3d scan iOS application.


    cv::Mat intrinMat(3,3,CV_64FC1);
    intrinMat.at<Float64>(0,0) = intrinsics.columns[0][0];
    intrinMat.at<Float64>(0,1) = intrinsics.columns[1][0];
    intrinMat.at<Float64>(0,2) = intrinsics.columns[2][0];
    intrinMat.at<Float64>(1,0) = intrinsics.columns[0][1];
    intrinMat.at<Float64>(1,1) = intrinsics.columns[1][1];
    intrinMat.at<Float64>(1,2) = intrinsics.columns[2][1];
    intrinMat.at<Float64>(2,0) = intrinsics.columns[0][2];
    intrinMat.at<Float64>(2,1) = intrinsics.columns[1][2];
    intrinMat.at<Float64>(2,2) = intrinsics.columns[2][2];
    
    std::vector<cv::Vec3d> rvecs, tvecs;
    //cv::Mat distCoeffs = cv::Mat::zeros(8, 1, CV_64F);
    cv::Mat distCoeffs = cv::Mat::zeros(14, 1, CV_64FC1);
    //cv::Mat distCoeffs;
    
    detect(dictionary, corners, ids, pixelBuffer);
    NSMutableArray *arrayMatrix = [NSMutableArray new];
    
    if(ids.size() == 0) {
        return arrayMatrix;
    }
    
    //cv::aruco::estimatePoseSingleMarkers(corners, markerSize, intrinMat, distCoeffs, rvecs, tvecs);
    cv::aruco::estimatePoseBoard(corners, ids, charucoBoard, intrinMat, distCoeffs, rvecs, tvecs);
    
    
    NSLog(@"found: rvecs.size(): %lu", rvecs.size());
    cv::Mat rotMat, tranMat;
    for (int i = 0; i < rvecs.size(); i++) {
        cv::Rodrigues(rvecs[i], rotMat);
        cv::Mat extrinsics = rotateRodriques(rotMat, tvecs[i]);
        SCNMatrix4 scnMatrix = [ArucoCV transformToSceneKitMatrix:extrinsics];
        SKWorldTransform *transform = [SKWorldTransform new];
        transform.arucoId = ids[i];
        transform.transform = scnMatrix;
        [arrayMatrix addObject:transform];
    }
    
    return arrayMatrix;
}

my code works fine when its estimatePoseSingleMarker But I get error when estimateposeboard

terminating with uncaught exception of type cv::Exception: OpenCV(4.1.2) /Users/5dof/Downloads/opencv/opencv-4.1.2/modules/core/src/copy.cpp:254: error: (-215:Assertion failed) channels() == CV_MAT_CN(dtype) in function ‘copyTo’

I am not using any copy methods, I have tried to change to all 4 channels. no luck.
please tell me what I am missing.

I didn’t check that your code is actually supposed to work. use official examples, don’t modify anything yourself. make sure that works.

write C++ or python code and make sure that works. then port to Objective C++ or whatever language that is you have there.


Note: OpenCV’s charuco is currently “broken”. there are several issues on OpenCV’s github.

the charuco code currently doesn’t work with old charuco boards. either make a new board that’s compatible with the version of OpenCV you currently use, or browse the repository for those bugfixes that allow it to deal with “legacy” boards.

1 Like

I am newbie in opencv, I am trying to develop an iOS application, I have the opencv version 4.1 and I am working using compatible charuco board, the same application works fine on android.

I have updated the opencv library to the latest code aswell. I still see the same copy issue.
updating the entire code :slight_smile:

’ ’ ’

static void detect(cv::Ptr<cv::aruco::Dictionary> &dictionary,std::vector<std::vector<cv::Point2f> > &corners, std::vector<int> &ids, CVPixelBufferRef pixelBuffer) {

// grey scale channel at 0
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
void *baseaddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
CGFloat width = CVPixelBufferGetWidth(pixelBuffer);
CGFloat height = CVPixelBufferGetHeight(pixelBuffer);
cv::Mat mat(height, width, CV_8UC1, baseaddress, 0); //CV_8UC1

cv::aruco::detectMarkers(mat,dictionary,corners,ids);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}

+(NSMutableArray *) estimatePose:(CVPixelBufferRef)pixelBuffer withIntrinsics:(matrix_float3x3)intrinsics andMarkerSize:(Float64)markerSize {
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::CharucoBoard> charucoBoard = cv::aruco::CharucoBoard::create(5, 7, 0.03636f, 0.02951f, dictionary);
std::vector<int> ids;
std::vector<std::vector<cv::Point2f>> corners;
detect(dictionary, corners, ids, pixelBuffer);

NSMutableArray *arrayMatrix = [NSMutableArray new];
if(ids.size() == 0) {
    return arrayMatrix;
}

cv::Mat intrinMat(3,3,CV_64F);
intrinMat.at<Float64>(0,0) = intrinsics.columns[0][0];
intrinMat.at<Float64>(0,1) = intrinsics.columns[1][0];
intrinMat.at<Float64>(0,2) = intrinsics.columns[2][0];
intrinMat.at<Float64>(1,0) = intrinsics.columns[0][1];
intrinMat.at<Float64>(1,1) = intrinsics.columns[1][1];
intrinMat.at<Float64>(1,2) = intrinsics.columns[2][1];
intrinMat.at<Float64>(2,0) = intrinsics.columns[0][2];
intrinMat.at<Float64>(2,1) = intrinsics.columns[1][2];
intrinMat.at<Float64>(2,2) = intrinsics.columns[2][2];

std::vector<cv::Vec3d> rvecs, tvecs;
cv::Mat distCoeffs = cv::Mat::zeros(8, 1, CV_64F);
//cv::aruco::estimatePoseSingleMarkers(corners, markerSize, intrinMat, distCoeffs, rvecs, tvecs);
cv::aruco::estimatePoseBoard(corners, ids, charucoBoard, intrinMat, distCoeffs, rvecs, tvecs);
NSLog(@"found: rvecs.size(): %lu", rvecs.size());


cv::Mat rotMat, tranMat;
for (int i = 0; i < rvecs.size(); i++) {
    cv::Rodrigues(rvecs[i], rotMat);
    cv::Mat extrinsics = rotateRodriques(rotMat, tvecs[i]);
    SCNMatrix4 scnMatrix = [ArucoCV transformToSceneKitMatrix:extrinsics];
    SKWorldTransform *transform = [SKWorldTransform new];
    transform.arucoId = ids[i];
    transform.transform = scnMatrix;
    [arrayMatrix addObject:transform];
}

return arrayMatrix;
}

error:
terminating with uncaught exception of type cv::Exception: OpenCV(4.6.0) /Users/runner/work/opencv-contrib-ios/opencv-contrib-ios/opencv-4.6.0/modules/core/src/copy.cpp:320: error: (-215:Assertion failed) channels() == CV_MAT_CN(dtype) in function ‘copyTo’