From bb71fe50930f5669a7a325e0fa95fee559856793 Mon Sep 17 00:00:00 2001 From: Michele Di Giorgio Date: Wed, 20 Jun 2018 11:45:35 +0100 Subject: COMPMID-1253: Nightly: Fix Canny Edge NEON failing Change-Id: If0836522792717a843c1cab405afc9320ce53079 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/137162 Tested-by: Jenkins Reviewed-by: Anthony Barbier --- src/runtime/NEON/functions/NECannyEdge.cpp | 2 +- tests/validation/Helpers.cpp | 2 +- tests/validation/reference/CannyEdgeDetector.cpp | 60 +++++++++++++++--------- 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(0, params.upper_thresh); + threshold_dist = std::uniform_int_distribution(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 -void trace_edge(SimpleTensor &dst, SimpleTensor &grad_mag, const ValidRegion &valid_region, std::vector &visited, uint32_t upper_thresh, const F &pixel_at_offset) +template +void trace_edge(SimpleTensor &dst) { + std::stack 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 neighbours = + std::array 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 canny_edge_detector_impl(const SimpleTensor &src, int32_t upp } // Final edge tracing - std::vector visited(dst.num_elements(), false); - trace_edge(dst, grad_mag, valid_region, visited, upper_thresh, pixel_at_offset); + trace_edge(dst); return dst; } } // namespace -- cgit v1.2.1