25 #if defined(SL_OS_WINDOWS)
47 _matcher = cv::BFMatcher::create(cv::BFMatcher::BRUTEFORCE_HAMMING,
false);
60 #ifdef DEBUG_OUTPUT_PATH
61 # if defined(SL_OS_LINUX) || defined(SL_OS_MACOS) || defined(SL_OS_MACIOS)
62 mkdir(DEBUG_OUTPUT_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
63 # elif defined(SL_OS_WINDOWS)
64 _mkdir(DEBUG_OUTPUT_PATH);
66 # undef SAVE_SNAPSHOTS_OUTPUT
74 #if DO_FEATURE_BENCHMARKING
77 Utils::log(
"------------------------------------------------------------------");
79 Utils::log(
"------------------------------------------------------------------");
80 Utils::log(
"Avg calculation time per frame : %f ms", _trackingTimesMS().average());
82 Utils::log(
"Settings for Pose estimation: ------------------------------------");
92 Utils::log(
"Pose information: ------------------------------------------------");
112 string msg =
"CVTrackedFeatures::loadMarker: File not found: " +
122 #ifndef SL_EMSCRIPTEN
155 CVPoint2f refImageKeypoint = keypoint.pt;
158 refImageKeypoint /= pixelPerMM;
169 #if defined(DEBUG_OUTPUT_PATH) || DRAW_REPROJECTION_POINTS
190 originalModelPoint.y - 1),
191 FONT_HERSHEY_SIMPLEX,
222 assert(!image.empty() &&
"Image is empty");
223 assert(!calib->
cameraMat().empty() &&
"Calibration is empty");
245 if (relocationNeeded)
313 cv::Scalar(0, 0, 255));
316 #if DRAW_REPROJECTION_POINTS
318 #elif defined(SAVE_SNAPSHOTS_OUTPUT)
319 CVMat imgReprojection;
323 #if DRAW_REPROJECTION_POINTS || defined(DEBUG_OUTPUT_PATH)
339 CVPoint2f projectedModelPoint = projectedPoints[i];
343 circle(imgReprojection,
350 circle(imgReprojection,
358 putText(imgReprojection,
360 CVPoint2f(projectedModelPoint.x - 2, projectedModelPoint.y - 5),
361 FONT_HERSHEY_SIMPLEX,
369 #if defined(DEBUG_OUTPUT_PATH)
372 drawMatches(imgReprojection,
381 imwrite(DEBUG_OUTPUT_PATH + to_string(
_frameCount) +
"_reprojection.png",
392 imwrite(DEBUG_OUTPUT_PATH + to_string(
_frameCount) +
"_keypoints.png",
415 imwrite(DEBUG_OUTPUT_PATH + to_string(
_frameCount) +
"_matching.png",
424 cvtColor(optFlow, rgb, CV_GRAY2BGR);
435 imwrite(DEBUG_OUTPUT_PATH + to_string(
_frameCount) +
"-optflow.png", rgb);
513 for (
auto& match : matches)
515 const cv::DMatch& match1 = match[0];
516 const cv::DMatch& match2 = match[1];
517 if (match2.distance == 0.0f ||
518 (match1.distance / match2.distance) <
minRatio)
519 goodMatches.push_back(match1);
593 vector<uchar> inliersMask(modelPoints.size());
599 bool foundPose = cv::solvePnPRansac(modelPoints,
613 for (
size_t idx : inliersMask)
642 cv::SOLVEPNP_ITERATIVE);
644 #if DO_FEATURE_BENCHMARKING
666 #if DO_FEATURE_BENCHMARKING
667 float reprojectionError = 0;
680 vector<size_t> frameIndicesInsideRect;
689 int alreadyMatched = 0;
698 if (alreadyMatched > 0)
continue;
701 CVPoint2f projectedModelPoint = projectedPoints[i];
712 bboxFrameKeypoints.clear();
713 frameIndicesInsideRect.clear();
718 int xTopLeft = (int)(projectedModelPoint.x - (
float)patchSize / 2.0f);
719 int yTopLeft = (int)(projectedModelPoint.y - (
float)patchSize / 2.0f);
720 int xDownRight = xTopLeft + patchSize;
721 int yDownRight = yTopLeft + patchSize;
731 frameIndicesInsideRect.push_back(j);
744 CVMat bboxPointsDescriptors;
745 for (
size_t j : frameIndicesInsideRect)
749 _matcher->match(bboxPointsDescriptors, modelPointDescriptor, newMatches);
752 if (!newMatches.empty())
754 for (
size_t j = 0; j < frameIndicesInsideRect.size(); j++)
756 newMatches[j].trainIdx = (int)i;
757 newMatches[j].queryIdx = (int)frameIndicesInsideRect[j];
762 bestNewMatch.distance = 0;
764 for (
CVDMatch newMatch : newMatches)
765 if (bestNewMatch.distance < newMatch.distance)
766 bestNewMatch = newMatch;
775 #if DO_FEATURE_BENCHMARKING
776 reprojectionError += (float)norm(
CVMat(projectedModelPoint),
777 CVMat(keypointForPose));
783 Point2f(projectedModelPoint.x - (
float)patchSize / 2.0f,
784 projectedModelPoint.y - (
float)patchSize / 2.0f),
785 Point2f(projectedModelPoint.x + (
float)patchSize / 2.0f,
786 projectedModelPoint.y + (
float)patchSize / 2.0f),
790 for (
const auto& kPt : bboxFrameKeypoints)
800 #if DO_FEATURE_BENCHMARKING
804 #if DO_FEATURE_BENCHMARKING
805 CVMat prevRmat, currRmat;
810 double rotationError_rad = acos((trace(prevRmat * currRmat).val[0] - 1.0) / 2.0);
816 #if DRAW_REPROJECTION_POINTS
821 FONT_HERSHEY_SIMPLEX,
836 if (modelPoints.empty())
return;
856 vector<uchar> status;
860 cv::TermCriteria criteria(cv::TermCriteria::COUNT | cv::TermCriteria::EPS,
868 cv::calcOpticalFlowPyrLK(
884 for (
size_t i = 0; i < status.size(); i++)
888 frame2DPoints.push_back(pred2DPoints[i]);
909 bool foundPose = cv::solvePnP(model3DPoints,
916 bool poseValid =
true;
920 for (
int i = 0; i < tvec.cols; i++)
922 if (
abs(tvec.at<
double>(i, 0) - tvec.at<
double>(i, 0)) >
abs(tvec.at<
double>(i, 0)) * 0.2)
924 cout <<
"translation too large" << endl;
928 for (
int i = 0; i < rvec.cols; i++)
930 if (
abs(rvec.at<
double>(i, 0) - rvec.at<
double>(i, 0)) > 0.174533)
932 cout <<
"rotation too large" << endl;
938 if (foundPose && poseValid)
946 return foundPose && poseValid;
CVDetectDescribeType
Feature detector-decriptor types.
double sum_reprojection_error
float sum_allmatches_to_inliers
float sum_poseopt_difference
int frames_since_posefound
const int reposeFrequency
const float reprojection_error
const int initialPatchSize
vector< cv::Point3f > CVVPoint3f
vector< vector< cv::DMatch > > CVVVDMatch
vector< cv::Point2f > CVVPoint2f
vector< cv::DMatch > CVVDMatch
vector< cv::KeyPoint > CVVKeyPoint
Live video camera calibration class with OpenCV an OpenCV calibration.
const CVMat & cameraMat() const
const CVMat & distortion() const
void createDetectorDescriptor(CVDetectDescribeType detectDescribeType)
Creates a detector and decriptor to the passed type.
void detectAndDescribe(CVInputArray image, CVVKeyPoint &keypoints, CVOutputArray descriptors, CVInputArray mask=cv::noArray())
OpenCV image class with the same interface as the former SLImage class.
bool _isTracking
True if tracking.
void loadMarker(string markerFilename)
Loads the marker image form the filesystem.
CVVDMatch getFeatureMatches()
SLFrameData _prevFrame
The previous video frame data.
CVTrackedFeatures(string markerFilename)
CVFeatureManager _featureManager
Feature detector-descriptor wrapper instance.
~CVTrackedFeatures()
Show statistics if program terminates.
bool _forceRelocation
Force relocation every frame (no opt. flow tracking)
SLFeatureMarker2D _marker
2D marker data
cv::Ptr< cv::DescriptorMatcher > _matcher
Descriptor matching algorithm.
CVCalibration * _calib
Current calibration in use.
void drawDebugInformation(bool drawDetection)
void initFeaturesOnMarker()
CVDetectDescribeType type()
bool track(CVMat imageGray, CVMat image, CVCalibration *calib) final
int _frameCount
NO. of frames since process start.
void detectKeypointsAndDescriptors()
bool trackWithOptFlow(CVMat rvec, CVMat tvec)
SLFrameData _currentFrame
The current video frame data.
static AvgFloat optFlowTimesMS
Averaged time for video feature optical flow tracking in ms.
CVMatx44f _objectViewMat
view transformation matrix
static AvgFloat detectTimesMS
Averaged time for video feature detection & description in ms.
bool _drawDetection
Flag if detection should be drawn into image.
static cv::Matx44f createGLMatrix(const CVMat &tVec, const CVMat &rVec)
Create an OpenGL 4x4 matrix from an OpenCV translation & rotation vector.
HighResTimer _timer
High resolution timer.
static AvgFloat matchTimesMS
Averaged time for video feature matching in ms.
static AvgFloat poseTimesMS
Averaged time for video feature pose estimation in ms.
float elapsedTimeInMilliSec()
void set(T value)
Sets the current value in the value array and builds the average.
bool exists(std::string path, SLIOStreamKind kind)
Checks whether a given file exists.
void exitMsg(const char *tag, const char *msg, const int line, const char *file)
Terminates the application with a message. No leak checking.
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
CVMat imageGray
Grayscale image of the marker.
CVVPoint3f keypoints3D
3D feature points in mm
CVVKeyPoint keypoints2D
2D keypoints in pixels
CVMat descriptors
Descriptors of the 2D keypoints.
CVMat imageDrawing
Color debug image.
CVVDMatch inlierMatches
matches that lead to correct transform
bool useExtrinsicGuess
flag if extrinsic gues should be used
bool foundPose
True if pose was found.
CVMat rvec
Rotation of the camera pose.
CVMat imageGray
Reference to grayscale video frame.
float reprojectionError
Reprojection error of the pose.
CVMat tvec
Translation of the camera pose.
CVVPoint2f inlierPoints2D
Inlier 2D points after RANSAC.
CVVDMatch matches
matches between video decriptors and marker descriptors
CVMat image
Reference to color video frame.
CVVKeyPoint keypoints
2D keypoints detected in video frame
CVVPoint3f inlierPoints3D
Inlier 3D points after RANSAC on the marker.
CVMat descriptors
Descriptors of keypoints.