mirror of
https://github.com/zebrajr/opencv.git
synced 2025-12-06 00:19:46 +01:00
Speedup ChArUco by avoiding temporary copies
This speeds up processing a 132x128 board by more than 100 times. This methods return std::vectors<> which means lots of copies and allocations.
This commit is contained in:
parent
6f040337e9
commit
6f9f8f49dd
|
|
@ -32,8 +32,10 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
const Mat chIds = charucoIds.getMat();
|
||||
const vector<int>& boardIds = board.getIds();
|
||||
|
||||
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx();
|
||||
vector<Point2f> distance(board.getNearestMarkerIdx().size(), Point2f(0.f, std::numeric_limits<float>::max()));
|
||||
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
|
||||
const vector<vector<int> > nearestMarkerCorners = board.getNearestMarkerCorners();
|
||||
|
||||
vector<Point2f> distance(nearestMarkerIdx.size(), Point2f(0.f, std::numeric_limits<float>::max()));
|
||||
// distance[i].x: max distance from the i-th charuco corner to charuco corner-forming markers.
|
||||
// The two charuco corner-forming markers of i-th charuco corner are defined in getNearestMarkerIdx()[i]
|
||||
// distance[i].y: min distance from the charuco corner to other markers.
|
||||
|
|
@ -52,7 +54,7 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
const int nearestMarkerId1 = boardIds[nearestMarkerIdx[chId][0]];
|
||||
const int nearestMarkerId2 = boardIds[nearestMarkerIdx[chId][1]];
|
||||
if (nearestMarkerId1 == idMaker || nearestMarkerId2 == idMaker) {
|
||||
int nearestCornerId = nearestMarkerId1 == idMaker ? board.getNearestMarkerCorners()[chId][0] : board.getNearestMarkerCorners()[chId][1];
|
||||
int nearestCornerId = nearestMarkerId1 == idMaker ? nearestMarkerCorners[chId][0] : nearestMarkerCorners[chId][1];
|
||||
Point2f nearestCorner = mCorners[j].ptr<Point2f>(0)[nearestCornerId];
|
||||
// distToNearest: distance from the charuco corner to charuco corner-forming markers
|
||||
float distToNearest = sqrt(normL2Sqr<float>(nearestCorner - charucoCorner));
|
||||
|
|
@ -84,18 +86,21 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
InputArray charucoCorners) {
|
||||
size_t nCharucoCorners = charucoCorners.getMat().total();
|
||||
|
||||
CV_Assert(board.getNearestMarkerIdx().size() == nCharucoCorners);
|
||||
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
|
||||
const vector<vector<int> > nearestMarkerCorners = board.getNearestMarkerCorners();
|
||||
|
||||
CV_Assert(nearestMarkerIdx.size() == nCharucoCorners);
|
||||
|
||||
vector<Size> winSizes(nCharucoCorners, Size(-1, -1));
|
||||
for(size_t i = 0ull; i < nCharucoCorners; i++) {
|
||||
if(charucoCorners.getMat().at<Point2f>((int)i) == Point2f(-1.f, -1.f)) continue;
|
||||
if(board.getNearestMarkerIdx()[i].empty()) continue;
|
||||
if(nearestMarkerIdx[i].empty()) continue;
|
||||
double minDist = -1;
|
||||
int counter = 0;
|
||||
// calculate the distance to each of the closest corner of each closest marker
|
||||
for(size_t j = 0; j < board.getNearestMarkerIdx()[i].size(); j++) {
|
||||
for(size_t j = 0; j < nearestMarkerIdx[i].size(); j++) {
|
||||
// find marker
|
||||
int markerId = board.getIds()[board.getNearestMarkerIdx()[i][j]];
|
||||
int markerId = board.getIds()[nearestMarkerIdx[i][j]];
|
||||
int markerIdx = -1;
|
||||
for(size_t k = 0; k < markerIds.getMat().total(); k++) {
|
||||
if(markerIds.getMat().at<int>((int)k) == markerId) {
|
||||
|
|
@ -105,7 +110,7 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
}
|
||||
if(markerIdx == -1) continue;
|
||||
Point2f markerCorner =
|
||||
markerCorners.getMat(markerIdx).at<Point2f>(board.getNearestMarkerCorners()[i][j]);
|
||||
markerCorners.getMat(markerIdx).at<Point2f>(nearestMarkerCorners[i][j]);
|
||||
Point2f charucoCorner = charucoCorners.getMat().at<Point2f>((int)i);
|
||||
double dist = norm(markerCorner - charucoCorner);
|
||||
if(minDist == -1) minDist = dist; // if first distance, just assign it
|
||||
|
|
@ -212,6 +217,8 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
vector<Mat> transformations(nMarkers);
|
||||
vector<bool> validTransform(nMarkers, false);
|
||||
const auto& ids = board.getIds();
|
||||
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
|
||||
|
||||
for(size_t i = 0ull; i < nMarkers; i++) {
|
||||
vector<Point2f> markerObjPoints2D;
|
||||
int markerId = markerIds.getMat().at<int>((int)i);
|
||||
|
|
@ -227,15 +234,16 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
double det = determinant(transformations[i]);
|
||||
validTransform[i] = std::abs(det) > 1e-6;
|
||||
}
|
||||
size_t nCharucoCorners = (size_t)board.getChessboardCorners().size();
|
||||
const vector<Point3f> chessboardCorners = board.getChessboardCorners();
|
||||
size_t nCharucoCorners = (size_t)chessboardCorners.size();
|
||||
vector<Point2f> allChessboardImgPoints(nCharucoCorners, Point2f(-1, -1));
|
||||
// for each charuco corner, calculate its interpolation position based on the closest markers
|
||||
// homographies
|
||||
for(size_t i = 0ull; i < nCharucoCorners; i++) {
|
||||
Point2f objPoint2D = Point2f(board.getChessboardCorners()[i].x, board.getChessboardCorners()[i].y);
|
||||
Point2f objPoint2D = Point2f(chessboardCorners[i].x, chessboardCorners[i].y);
|
||||
vector<Point2f> interpolatedPositions;
|
||||
for(size_t j = 0ull; j < board.getNearestMarkerIdx()[i].size(); j++) {
|
||||
int markerId = board.getIds()[board.getNearestMarkerIdx()[i][j]];
|
||||
for(size_t j = 0ull; j < nearestMarkerIdx[i].size(); j++) {
|
||||
int markerId = board.getIds()[nearestMarkerIdx[i][j]];
|
||||
int markerIdx = -1;
|
||||
for(size_t k = 0ull; k < markerIds.getMat().total(); k++) {
|
||||
if(markerIds.getMat().at<int>((int)k) == markerId) {
|
||||
|
|
@ -274,13 +282,14 @@ struct CharucoDetector::CharucoDetectorImpl {
|
|||
CV_Assert(charucoParameters.minMarkers >= 0 && charucoParameters.minMarkers <= 2);
|
||||
vector<Point2f> filteredCharucoCorners;
|
||||
vector<int> filteredCharucoIds;
|
||||
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
|
||||
// for each charuco corner
|
||||
for(unsigned int i = 0; i < allCharucoIds.getMat().total(); i++) {
|
||||
int currentCharucoId = allCharucoIds.getMat().at<int>(i);
|
||||
int totalMarkers = 0; // nomber of closest marker detected
|
||||
// look for closest markers
|
||||
for(unsigned int m = 0; m < board.getNearestMarkerIdx()[currentCharucoId].size(); m++) {
|
||||
int markerId = board.getIds()[board.getNearestMarkerIdx()[currentCharucoId][m]];
|
||||
for(unsigned int m = 0; m < nearestMarkerIdx[currentCharucoId].size(); m++) {
|
||||
int markerId = board.getIds()[nearestMarkerIdx[currentCharucoId][m]];
|
||||
bool found = false;
|
||||
for(unsigned int k = 0; k < allArucoIds.getMat().total(); k++) {
|
||||
if(allArucoIds.getMat().at<int>(k) == markerId) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user