mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2026-08-06 11:42:26 +02:00
added functionality to merge rois
This commit is contained in:
+3
-1
@@ -414,7 +414,8 @@ set(PUBLICHEADERS
|
||||
include/aare/RawMasterFile.hpp
|
||||
include/aare/RawSubFile.hpp
|
||||
include/aare/VarClusterFinder.hpp
|
||||
include/aare/utils/task.hpp)
|
||||
include/aare/utils/task.hpp
|
||||
include/aare/utils/utility_functions.hpp)
|
||||
|
||||
set(SourceFiles
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/calibration.cpp
|
||||
@@ -507,6 +508,7 @@ if(AARE_TESTS)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawSubFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/task.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/utility_functions.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/to_string.test.cpp)
|
||||
target_sources(tests PRIVATE ${TestSources})
|
||||
endif()
|
||||
|
||||
@@ -186,6 +186,11 @@ struct ROI {
|
||||
bool contains(ssize_t x, ssize_t y) const {
|
||||
return x >= xmin && x < xmax && y >= ymin && y < ymax;
|
||||
}
|
||||
|
||||
bool operator==(const ROI &other) const {
|
||||
return xmin == other.xmin && xmax == other.xmax && ymin == other.ymin &&
|
||||
ymax == other.ymax;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Chip specifications for Matterhorn1
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
#include "aare/defs.hpp"
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace aare {
|
||||
|
||||
/**
|
||||
* @brief Merge all consecutive ROIs in a vector into a single ROI.
|
||||
* @param rois vector of ROIs to merge
|
||||
* @return vector of merged ROIs
|
||||
* @tparam horizontally_aligned true if the ROIs are horizontally aligned, false
|
||||
* otherwise
|
||||
* @tparam vertically_aligned true if the ROIs are vertically aligned, false
|
||||
* otherwise
|
||||
*/
|
||||
template <bool horizontally_aligned = false, bool vertically_aligned = false>
|
||||
std::vector<ROI> merge_consecutive_rois(std::vector<ROI> &rois) {
|
||||
|
||||
if constexpr (horizontally_aligned && vertically_aligned) {
|
||||
throw std::runtime_error(
|
||||
LOCATION + "Vector of the same ROI? Cannot merge ROIs both "
|
||||
"horizontally and vertically at the same time.");
|
||||
}
|
||||
|
||||
if (rois.empty()) {
|
||||
return {};
|
||||
}
|
||||
if (rois.size() == 1) {
|
||||
return rois;
|
||||
}
|
||||
|
||||
auto merge_along_x = [](std::vector<ROI> in_rois) {
|
||||
std::sort(in_rois.begin(), in_rois.end(),
|
||||
[](const ROI &a, const ROI &b) {
|
||||
return (a.ymin != b.ymin) ? (a.ymin < b.ymin)
|
||||
: (a.xmin < b.xmin);
|
||||
}); // N log (N)
|
||||
|
||||
std::vector<ROI> merged_rois;
|
||||
merged_rois.reserve(in_rois.size());
|
||||
merged_rois.push_back(in_rois[0]);
|
||||
|
||||
for (size_t i = 1; i < in_rois.size(); ++i) {
|
||||
auto &last = merged_rois.back();
|
||||
const auto ¤t = in_rois[i];
|
||||
if (last.ymin == current.ymin && last.ymax == current.ymax &&
|
||||
last.xmax == current.xmin) {
|
||||
// merge
|
||||
last.xmax = current.xmax;
|
||||
} else {
|
||||
merged_rois.push_back(current);
|
||||
}
|
||||
}
|
||||
return merged_rois;
|
||||
};
|
||||
|
||||
auto merge_along_y = [](std::vector<ROI> in_rois) {
|
||||
std::sort(in_rois.begin(), in_rois.end(),
|
||||
[](const ROI &a, const ROI &b) {
|
||||
return (a.xmin != b.xmin) ? (a.xmin < b.xmin)
|
||||
: (a.ymin < b.ymin);
|
||||
});
|
||||
|
||||
std::vector<ROI> merged_rois;
|
||||
merged_rois.reserve(in_rois.size());
|
||||
merged_rois.push_back(in_rois[0]);
|
||||
|
||||
for (size_t i = 1; i < in_rois.size(); ++i) {
|
||||
auto &last = merged_rois.back();
|
||||
const auto ¤t = in_rois[i];
|
||||
if (last.xmin == current.xmin && last.xmax == current.xmax &&
|
||||
last.ymax == current.ymin) {
|
||||
last.ymax = current.ymax;
|
||||
} else {
|
||||
merged_rois.push_back(current);
|
||||
}
|
||||
}
|
||||
return merged_rois;
|
||||
};
|
||||
|
||||
if constexpr (horizontally_aligned) {
|
||||
return merge_along_y(rois); // one sort + one pass
|
||||
} else if constexpr (vertically_aligned) {
|
||||
return merge_along_x(rois); // one sort + one pass
|
||||
} else {
|
||||
return merge_along_y(merge_along_x(rois)); // generic case: two passes
|
||||
}
|
||||
}
|
||||
} // namespace aare
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "aare/utils/utility_functions.hpp"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
namespace aare {
|
||||
|
||||
TEST_CASE("merge ROIs", "[utility_functions]") {
|
||||
|
||||
SECTION("not fully contiguous") {
|
||||
|
||||
std::vector<ROI> rois = {ROI{20, 30, 50, 60}, ROI{20, 30, 40, 50},
|
||||
ROI{10, 20, 40, 50}};
|
||||
|
||||
auto merged_rois = merge_consecutive_rois<false, false>(rois);
|
||||
|
||||
REQUIRE(merged_rois.size() == 2);
|
||||
|
||||
REQUIRE(merged_rois[0] == ROI{10, 30, 40, 50});
|
||||
REQUIRE(merged_rois[1] == ROI{20, 30, 50, 60});
|
||||
}
|
||||
SECTION("complex merge") {
|
||||
|
||||
std::vector<ROI> rois = {ROI{40, 50, 20, 30}, ROI{10, 20, 30, 40},
|
||||
ROI{10, 20, 50, 60}, ROI{20, 30, 30, 40},
|
||||
ROI{60, 70, 30, 40}, ROI{60, 70, 20, 30},
|
||||
ROI{20, 30, 20, 30}, ROI{10, 20, 20, 30}};
|
||||
|
||||
auto merged_rois = merge_consecutive_rois<false, false>(rois);
|
||||
|
||||
REQUIRE(merged_rois.size() == 4);
|
||||
|
||||
REQUIRE(merged_rois[0] == ROI{10, 30, 20, 40});
|
||||
REQUIRE(merged_rois[1] == ROI{10, 20, 50, 60});
|
||||
REQUIRE(merged_rois[2] == ROI{40, 50, 20, 30});
|
||||
REQUIRE(merged_rois[3] == ROI{60, 70, 20, 40});
|
||||
}
|
||||
SECTION("horizontally aligned") {
|
||||
std::vector<ROI> rois = {ROI{10, 20, 30, 40}, ROI{10, 20, 50, 60},
|
||||
ROI{10, 20, 20, 30}};
|
||||
|
||||
auto merged_rois = merge_consecutive_rois<true, false>(rois);
|
||||
|
||||
REQUIRE(merged_rois.size() == 2);
|
||||
REQUIRE(merged_rois[0] == ROI{10, 20, 20, 40});
|
||||
REQUIRE(merged_rois[1] == ROI{10, 20, 50, 60});
|
||||
}
|
||||
SECTION("vertically aligned") {
|
||||
std::vector<ROI> rois = {ROI{10, 20, 30, 40}, ROI{30, 40, 30, 40},
|
||||
ROI{20, 30, 30, 40}};
|
||||
|
||||
auto merged_rois = merge_consecutive_rois<false, true>(rois);
|
||||
|
||||
REQUIRE(merged_rois.size() == 1);
|
||||
REQUIRE(merged_rois[0] == ROI{10, 40, 30, 40});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aare
|
||||
Reference in New Issue
Block a user