| 36 | const camera_specs_t CameraDatabase::specs_ = InitializeCameraSpecs(); |
| 37 | |
| 38 | bool CameraDatabase::QuerySensorWidth(const std::string& make, |
| 39 | const std::string& model, |
| 40 | double* sensor_width_mm) { |
| 41 | // Clean the strings from all separators. |
| 42 | std::string cleaned_make = make; |
| 43 | std::string cleaned_model = model; |
| 44 | cleaned_make = StringReplace(cleaned_make, " ", ""); |
| 45 | cleaned_model = StringReplace(cleaned_model, " ", ""); |
| 46 | cleaned_make = StringReplace(cleaned_make, "-", ""); |
| 47 | cleaned_model = StringReplace(cleaned_model, "-", ""); |
| 48 | StringToLower(&cleaned_make); |
| 49 | StringToLower(&cleaned_model); |
| 50 | |
| 51 | // Make sure that make name is not duplicated. |
| 52 | cleaned_model = StringReplace(cleaned_model, cleaned_make, ""); |
| 53 | |
| 54 | // Check if cleaned_make exists in database: Test whether EXIF string is |
| 55 | // substring of database entry and vice versa. |
| 56 | size_t spec_matches = 0; |
| 57 | for (const auto& [make_name, models] : specs_) { |
| 58 | if (StringContains(cleaned_make, make_name) || |
| 59 | StringContains(make_name, cleaned_make)) { |
| 60 | for (const auto& [model_name, sensor_width] : models) { |
| 61 | if (StringContains(cleaned_model, model_name) || |
| 62 | StringContains(model_name, cleaned_model)) { |
| 63 | *sensor_width_mm = sensor_width; |
| 64 | if (cleaned_model == model_name) { |
| 65 | // Model exactly matches, return immediately. |
| 66 | return true; |
| 67 | } |
| 68 | spec_matches += 1; |
| 69 | if (spec_matches > 1) { |
| 70 | break; |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | // Only return unique results, if model does not exactly match. |
| 78 | return spec_matches == 1; |
| 79 | } |
| 80 | |
| 81 | } // namespace colmap |