ROIFilter: Add filter to only preserve ROI regions

This commit is contained in:
2023-06-23 13:47:07 +02:00
parent bbd0b6ef36
commit bd549bb339
2 changed files with 141 additions and 18 deletions
+30 -16
View File
@@ -10,35 +10,49 @@
#include "JFJochException.h"
class ROIFilter {
size_t width, height;
int32_t width, height;
std::vector<uint8_t> mask;
public:
ROIFilter(size_t in_width, size_t in_height, uint8_t fill_value = 0)
: width(in_width), height(in_height), mask (in_width * in_height, fill_value) {}
ROIFilter(int32_t in_width, int32_t in_height, uint8_t fill_value = 0)
: width(in_width), height(in_height) {
if ((width < 0) || (height < 0))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Negative dimensions are wrong");
mask = std::vector<uint8_t>(in_width * in_height, fill_value);
}
void SetRectangle(size_t x0, size_t y0, size_t in_width, size_t in_height, uint8_t fill_value = 1) {
if (y0 + in_height > height)
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Mismatch in array size");
if (x0 + in_width > width)
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Mismatch in array size");
void SetRectangle(int32_t x0, int32_t y0, int32_t in_width, int32_t in_height, uint8_t mask_value = 1) {
if (x0 < 0) { in_width += x0; x0 = 0; }
if (in_width <= 0) return;
for (size_t y = y0; y < y0 + in_height; y++) {
if (x0 >= width) return;
if (x0 + in_width >= width) in_width = width - 1 - x0;
if (y0 < 0) { in_height += y0; y0 = 0; }
if (in_height <= 0) return;
if (y0 >= height) return;
if (y0 + in_height >= height) in_height = height - 1 - y0;
for (size_t y = y0; y < y0 + in_height; y++) {
for (size_t x = x0; x < x0 + in_width; x++) {
mask[y * width + x] |= fill_value;
mask[y * width + x] |= mask_value;
}
}
}
void ClearRectangle(int32_t x0, int32_t y0, int32_t in_width, int32_t in_height, uint8_t mask_value = 1) {
if (x0 < 0) { in_width += x0; x0 = 0; }
if (in_width <= 0) return;
void ClearRectangle(size_t x0, size_t y0, size_t in_width, size_t in_height, uint8_t fill_value = 1) {
if (y0 + in_height > height)
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Mismatch in array size");
if (x0 + in_width > width)
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Mismatch in array size");
if (x0 >= width) return;
if (x0 + in_width >= width) in_width = width - 1 - x0;
if (y0 < 0) { in_height += y0; y0 = 0; }
if (in_height <= 0) return;
for (size_t y = y0; y < y0 + in_height; y++) {
for (size_t x = x0; x < x0 + in_width; x++) {
mask[y * width + x] &= ~fill_value;
mask[y * width + x] &= ~mask_value;
}
}
}
+111 -2
View File
@@ -6,8 +6,8 @@
#include "../common/ROIFilter.h"
TEST_CASE("ROIFilter") {
size_t width = 4;
size_t height = 5;
int32_t width = 4;
int32_t height = 5;
std::vector<uint32_t> v(width * height, 1);
ROIFilter filter(width, height);
@@ -27,3 +27,112 @@ TEST_CASE("ROIFilter") {
REQUIRE(v[width * 3 + 2] == 1);
REQUIRE(v[width * 4 + 2] == 55);
}
TEST_CASE("ROIFilter_out_of_bounds") {
int32_t width = 4;
int32_t height = 5;
std::vector<uint32_t> v(width * height, 1);
ROIFilter filter(width, height);
filter.SetRectangle(1, 5, 2, 3);
filter.SetRectangle(4, 1, 2, 3);
filter.Apply(v, (uint32_t) 55);
size_t diff = 0;
for (auto &i: v) {
if (i != 55)
diff++;
}
REQUIRE(diff == 0);
}
TEST_CASE("ROIFilter_negative_out_of_bounds") {
int32_t width = 4;
int32_t height = 5;
std::vector<uint32_t> v(width * height, 1);
ROIFilter filter(width, height);
filter.SetRectangle(1, -9, 2, 3);
filter.SetRectangle(-3, 1, 2, 3);
filter.Apply(v, (uint32_t) 55);
size_t diff = 0;
for (auto &i: v) {
if (i != 55)
diff++;
}
REQUIRE(diff == 0);
}
TEST_CASE("ROIFilter_on_bounds") {
int32_t width = 4;
int32_t height = 5;
std::vector<uint32_t> v(width * height, 1);
ROIFilter filter(width, height);
filter.SetRectangle(2, 3, 10, 10);
filter.Apply(v, (uint32_t) 55);
REQUIRE(v[1 * width + 0] == 55);
REQUIRE(v[1 * width + 1] == 55);
REQUIRE(v[1 * width + 2] == 55);
REQUIRE(v[1 * width + 3] == 55);
REQUIRE(v[2 * width + 0] == 55);
REQUIRE(v[2 * width + 1] == 55);
REQUIRE(v[2 * width + 2] == 55);
REQUIRE(v[2 * width + 3] == 55);
REQUIRE(v[3 * width + 0] == 55);
REQUIRE(v[3 * width + 1] == 55);
REQUIRE(v[3 * width + 2] == 1);
REQUIRE(v[3 * width + 3] == 1);
REQUIRE(v[4 * width + 0] == 55);
REQUIRE(v[4 * width + 1] == 55);
REQUIRE(v[4 * width + 2] == 1);
REQUIRE(v[4 * width + 3] == 1);
}
TEST_CASE("ROIFilter_negative_start") {
int32_t width = 4;
int32_t height = 5;
std::vector<uint32_t> v(width * height, 1);
ROIFilter filter(width, height);
filter.SetRectangle(-1, -1, 3, 4);
filter.Apply(v, (uint32_t) 55);
CHECK(v[0 * width + 0] == 1);
CHECK(v[0 * width + 1] == 1);
CHECK(v[0 * width + 2] == 55);
CHECK(v[0 * width + 3] == 55);
CHECK(v[1 * width + 0] == 1);
CHECK(v[1 * width + 1] == 1);
CHECK(v[1 * width + 2] == 55);
CHECK(v[1 * width + 3] == 55);
CHECK(v[2 * width + 0] == 1);
CHECK(v[2 * width + 1] == 1);
CHECK(v[2 * width + 2] == 55);
CHECK(v[2 * width + 3] == 55);
CHECK(v[3 * width + 0] == 55);
CHECK(v[3 * width + 1] == 55);
CHECK(v[3 * width + 2] == 55);
CHECK(v[3 * width + 3] == 55);
CHECK(v[4 * width + 0] == 55);
CHECK(v[4 * width + 1] == 55);
CHECK(v[4 * width + 2] == 55);
CHECK(v[4 * width + 3] == 55);
}