Trying to map the camera position from Aruco tracking back to the camera position in SceneKit. It's almost working but the tracking is really unstable and it appears the conversion to the SceneKit camera pose is incorrect as it's floating over the marker in the camera view and moving about as I move the camera around. Can anyone see what I may be doing wrong here in the conversion back to the sceneKit camera translation and position vectors?
@interface ArucoPayload : NSObject
@property BOOL valid; // Used to determine if the tracking was valid and hides the scenekit nodes if not
@property UIImage *image;
@property CGRect boardSize;
@property SCNVector4 rotationVector;
@property SCNVector3 translationVector;
@end
Mat rvec(3, 1, DataType<double>::type);
Mat tvec(3, 1, DataType<double>::type);
...
aruco::estimatePoseBoard(corners, markerIds, gridBoard, self.camMatrix, self.distCoeffs, rvec, tvec);
[self updateCameraProjection:payload withRotation:rvec andTranslation:tvec];
...
-(void) updateCameraProjection:(ArucoPayload *)payload withRotation:(Mat)rvec andTranslation:(Mat)tvec {
cv::Mat RotX(3, 3, cv::DataType<double>::type);
cv::setIdentity(RotX);
RotX.at<double>(4) = -1;
RotX.at<double>(8) = -1;
cv::Mat R;
cv::Rodrigues(rvec, R);
R = R.t();
Mat rvecConverted;
Rodrigues(R, rvecConverted);
rvecConverted = RotX * rvecConverted;
Mat tvecConverted = -R * tvec;
tvecConverted = RotX * tvecConverted;
payload.rotationVector = SCNVector4Make(rvecConverted.at<double>(0), rvecConverted.at<double>(1), rvecConverted.at<double>(2), norm(rvecConverted));
payload.translationVector = SCNVector3Make(tvecConverted.at<double>(0), tvecConverted.at<double>(1), tvecConverted.at<double>(2));
}
func updateCameraPosition(payload:ArucoPayload) {
if(payload.valid) {
sceneView.scene?.rootNode.isHidden = false
// Add nodes first time we get an updated position
if(sceneView.scene?.rootNode.childNodes.count == 1) {
// Add box node
addBoxNode(to: sceneView, payload: payload)
}
cameraNode.rotation = payload.rotationVector
cameraNode.position = payload.translationVector
} else {
sceneView.scene?.rootNode.isHidden = true
}
}
The drawing done in OpenCV is correct and my axis and frame around the Aruco board is tracking accurately as can be seen in the video.
Any help is much appreciated. Here is the video of the scene. The yellow object which should be locked to the position of the marker seems very unstable.
Camera Calibration:
// Wait until we have captured enough frames
if(self.numberOfFramesForCalibration == 0) {
NSLog(@"Starting calibration with 20 images");
vector< vector< Point2f > > allCornersConcatenated;
vector< int > allIdsConcatenated;
vector< int > markerCounterPerFrame;
Mat cameraMatrix, distCoeffs;
vector< Mat > rvecs, tvecs;
double repError;
int calibrationFlags = 0;
// prepare data for calibration
markerCounterPerFrame.reserve(allCorners.size());
for(unsigned int i = 0; i < allCorners.size(); i++) {
markerCounterPerFrame.push_back((int)allCorners[i].size());
for(unsigned int j = 0; j < allCorners[i].size(); j++) {
allCornersConcatenated.push_back(allCorners[i][j]);
allIdsConcatenated.push_back(allIds[i][j]);
}
}
// calibrate camera
repError = aruco::calibrateCameraAruco(allCornersConcatenated, allIdsConcatenated,
markerCounterPerFrame, self.data.board, imgSize, cameraMatrix,
distCoeffs, rvecs, tvecs);
bool saveOk = [self saveCameraParams:imgSize aspect:1 flags:calibrationFlags matrix:cameraMatrix coeff:distCoeffs avgErr:repError];
if(saveOk) {
self.calibrationRequired = false;
}
}