| 1330 | } |
| 1331 | |
| 1332 | void Match(const Image& image1, |
| 1333 | const Image& image2, |
| 1334 | FeatureMatches* matches) override { |
| 1335 | THROW_CHECK_NOTNULL(matches); |
| 1336 | ThrowCheckFeatureTypesMatch(image1, image2); |
| 1337 | |
| 1338 | matches->clear(); |
| 1339 | |
| 1340 | // Protect OpenGL operations with global mutex based on runtime backend |
| 1341 | std::unique_lock<std::mutex> lock; |
| 1342 | if (backend_ == SiftBackend::GLSL) { |
| 1343 | lock = std::unique_lock<std::mutex>( |
| 1344 | *sift_opengl_mutexes_.at(sift_match_gpu_.gpu_index)); |
| 1345 | } |
| 1346 | |
| 1347 | if (prev_image_id1_ == kInvalidImageId || prev_is_guided_ || |
| 1348 | prev_image_id1_ != image1.image_id) { |
| 1349 | WarnIfMaxNumMatchesReachedGPU(image1.descriptors->data); |
| 1350 | sift_match_gpu_.SetDescriptors( |
| 1351 | 0, image1.descriptors->data.rows(), image1.descriptors->data.data()); |
| 1352 | prev_image_id1_ = image1.image_id; |
| 1353 | } |
| 1354 | |
| 1355 | if (prev_image_id2_ == kInvalidImageId || prev_is_guided_ || |
| 1356 | prev_image_id2_ != image2.image_id) { |
| 1357 | WarnIfMaxNumMatchesReachedGPU(image2.descriptors->data); |
| 1358 | sift_match_gpu_.SetDescriptors( |
| 1359 | 1, image2.descriptors->data.rows(), image2.descriptors->data.data()); |
| 1360 | prev_image_id2_ = image2.image_id; |
| 1361 | } |
| 1362 | |
| 1363 | prev_is_guided_ = false; |
| 1364 | |
| 1365 | matches->resize(static_cast<size_t>(options_.max_num_matches)); |
| 1366 | |
| 1367 | const int num_matches = sift_match_gpu_.GetSiftMatch( |
| 1368 | options_.max_num_matches, |
| 1369 | reinterpret_cast<uint32_t (*)[2]>(matches->data()), |
| 1370 | static_cast<float>(options_.sift->max_distance), |
| 1371 | static_cast<float>(options_.sift->max_ratio), |
| 1372 | options_.sift->cross_check); |
| 1373 | |
| 1374 | if (num_matches < 0) { |
| 1375 | LOG(ERROR) << "Feature matching failed. This is probably caused by " |
| 1376 | "insufficient GPU memory. Consider reducing the maximum " |
| 1377 | "number of features and/or matches."; |
| 1378 | matches->clear(); |
| 1379 | } else { |
| 1380 | THROW_CHECK_LE(num_matches, matches->size()); |
| 1381 | matches->resize(num_matches); |
| 1382 | } |
| 1383 | } |
| 1384 | |
| 1385 | void MatchGuided(const double max_error, |
| 1386 | const Image& image1, |
nothing calls this directly
no test coverage detected