aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Di Giorgio <michele.digiorgio@arm.com>2018-06-20 11:45:35 +0100
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:53:21 +0000
commitbb71fe50930f5669a7a325e0fa95fee559856793 (patch)
tree41766578d900f805ae18c38702cdc382300b5fe3
parentd3a78ab634d3047bcb1615512b1b290dbfbca5f4 (diff)
downloadComputeLibrary-bb71fe50930f5669a7a325e0fa95fee559856793.tar.gz
COMPMID-1253: Nightly: Fix Canny Edge NEON failing
Change-Id: If0836522792717a843c1cab405afc9320ce53079 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/137162 Tested-by: Jenkins <bsgcomp@arm.com> Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
-rw-r--r--src/runtime/NEON/functions/NECannyEdge.cpp2
-rw-r--r--tests/validation/Helpers.cpp2
-rw-r--r--tests/validation/reference/CannyEdgeDetector.cpp60
3 files changed, 41 insertions, 23 deletions
diff --git a/src/runtime/NEON/functions/NECannyEdge.cpp b/src/runtime/NEON/functions/NECannyEdge.cpp
index 1d73148f47..d72c98bb50 100644
--- a/src/runtime/NEON/functions/NECannyEdge.cpp
+++ b/src/runtime/NEON/functions/NECannyEdge.cpp
@@ -66,7 +66,7 @@ void NECannyEdge::configure(ITensor *input, ITensor *output, int32_t upper_thr,
ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(output, 1, DataType::U8);
ARM_COMPUTE_ERROR_ON((1 != norm_type) && (2 != norm_type));
ARM_COMPUTE_ERROR_ON((gradient_size != 3) && (gradient_size != 5) && (gradient_size != 7));
- ARM_COMPUTE_ERROR_ON(lower_thr > upper_thr);
+ ARM_COMPUTE_ERROR_ON((lower_thr < 0) || (lower_thr >= upper_thr));
_output = output;
diff --git a/tests/validation/Helpers.cpp b/tests/validation/Helpers.cpp
index 521cc5724a..e2415a203e 100644
--- a/tests/validation/Helpers.cpp
+++ b/tests/validation/Helpers.cpp
@@ -141,7 +141,7 @@ CannyEdgeParameters canny_edge_parameters()
params.constant_border_value = int_dist(gen);
params.upper_thresh = threshold_dist(gen); // upper_threshold >= 1
- threshold_dist = std::uniform_int_distribution<uint8_t>(0, params.upper_thresh);
+ threshold_dist = std::uniform_int_distribution<uint8_t>(1, params.upper_thresh - 1);
params.lower_thresh = threshold_dist(gen);
return params;
diff --git a/tests/validation/reference/CannyEdgeDetector.cpp b/tests/validation/reference/CannyEdgeDetector.cpp
index 45b244f3c6..6fe4544cf6 100644
--- a/tests/validation/reference/CannyEdgeDetector.cpp
+++ b/tests/validation/reference/CannyEdgeDetector.cpp
@@ -49,38 +49,57 @@ const auto MARK_ZERO = 0u;
const auto MARK_MAYBE = 127u;
const auto MARK_EDGE = 255u;
-template <typename U, typename T, typename F>
-void trace_edge(SimpleTensor<T> &dst, SimpleTensor<U> &grad_mag, const ValidRegion &valid_region, std::vector<bool> &visited, uint32_t upper_thresh, const F &pixel_at_offset)
+template <typename T>
+void trace_edge(SimpleTensor<T> &dst)
{
+ std::stack<Coordinates> pixels_stack;
for(auto i = 0; i < dst.num_elements(); ++i)
{
- Coordinates coord;
- if(visited[i] || dst[i] != MARK_MAYBE || !is_in_valid_region(valid_region, coord = index2coord(dst.shape(), i)))
+ if(dst[i] == MARK_EDGE)
{
- continue; // Skip visited or confirmed ZERO/EDGE pixels
+ pixels_stack.push(index2coord(dst.shape(), i));
}
- visited[i] = true; // Mark as visited
+ }
+
+ while(!pixels_stack.empty())
+ {
+ const Coordinates pixel_coord = pixels_stack.top();
+ pixels_stack.pop();
- // Check if connected to a strong edge pixel
- std::array<U, 8> neighbours =
+ std::array<Coordinates, 8> neighbours =
{
{
- pixel_at_offset(grad_mag, coord, -1, 0),
- pixel_at_offset(grad_mag, coord, 1, 0),
- pixel_at_offset(grad_mag, coord, -1, -1),
- pixel_at_offset(grad_mag, coord, +1, +1),
- pixel_at_offset(grad_mag, coord, 0, -1),
- pixel_at_offset(grad_mag, coord, 0, +1),
- pixel_at_offset(grad_mag, coord, +1, -1),
- pixel_at_offset(grad_mag, coord, -1, +1)
+ Coordinates(pixel_coord.x() - 1, pixel_coord.y() + 0),
+ Coordinates(pixel_coord.x() + 1, pixel_coord.y() + 0),
+ Coordinates(pixel_coord.x() - 1, pixel_coord.y() - 1),
+ Coordinates(pixel_coord.x() + 1, pixel_coord.y() + 1),
+ Coordinates(pixel_coord.x() + 0, pixel_coord.y() - 1),
+ Coordinates(pixel_coord.x() + 0, pixel_coord.y() + 1),
+ Coordinates(pixel_coord.x() + 1, pixel_coord.y() - 1),
+ Coordinates(pixel_coord.x() - 1, pixel_coord.y() + 1)
}
};
- const auto is_edge_connected = std::any_of(neighbours.begin(), neighbours.end(), [&](const U & pixel)
+ // Mark MAYBE neighbours as edges since they are next to an EDGE
+ std::for_each(neighbours.begin(), neighbours.end(), [&](Coordinates & coord)
{
- return pixel >= upper_thresh;
+ const size_t pixel_index = coord2index(dst.shape(), coord);
+ const T pixel = dst[pixel_index];
+ if(pixel == MARK_MAYBE)
+ {
+ dst[pixel_index] = MARK_EDGE;
+ pixels_stack.push(coord);
+ }
});
- dst[i] = is_edge_connected ? MARK_EDGE : MARK_ZERO;
+ }
+
+ // Mark all remaining MAYBE pixels as ZERO (not edges)
+ for(auto i = 0; i < dst.num_elements(); ++i)
+ {
+ if(dst[i] == MARK_MAYBE)
+ {
+ dst[i] = MARK_ZERO;
+ }
}
}
@@ -202,8 +221,7 @@ SimpleTensor<T> canny_edge_detector_impl(const SimpleTensor<T> &src, int32_t upp
}
// Final edge tracing
- std::vector<bool> visited(dst.num_elements(), false);
- trace_edge<unsigned_U>(dst, grad_mag, valid_region, visited, upper_thresh, pixel_at_offset);
+ trace_edge<T>(dst);
return dst;
}
} // namespace