| 152 | } |
| 153 | |
| 154 | pair<Array<char>, Array<char>> computeCandidates(const Array<float>& supEdges, |
| 155 | const float t1, |
| 156 | const af_canny_threshold ct, |
| 157 | const float t2) { |
| 158 | float maxVal = |
| 159 | getScalar<float>(reduce_all<af_max_t, float, float>(supEdges)); |
| 160 | ; |
| 161 | auto NUM_BINS = static_cast<unsigned>(maxVal); |
| 162 | |
| 163 | auto lowRatio = createValueArray<float>(supEdges.dims(), t1); |
| 164 | |
| 165 | switch (ct) { // NOLINT(hicpp-multiway-paths-covered) |
| 166 | case AF_CANNY_THRESHOLD_AUTO_OTSU: { |
| 167 | auto T2 = otsuThreshold(supEdges, NUM_BINS, maxVal); |
| 168 | auto T1 = arithOp<float, af_mul_t>(T2, lowRatio, T2.dims()); |
| 169 | Array<char> weak1 = |
| 170 | logicOp<float, af_ge_t>(supEdges, T1, supEdges.dims()); |
| 171 | Array<char> weak2 = |
| 172 | logicOp<float, af_lt_t>(supEdges, T2, supEdges.dims()); |
| 173 | Array<char> weak = |
| 174 | logicOp<char, af_and_t>(weak1, weak2, weak1.dims()); |
| 175 | Array<char> strong = |
| 176 | logicOp<float, af_ge_t>(supEdges, T2, supEdges.dims()); |
| 177 | return make_pair(strong, weak); |
| 178 | }; |
| 179 | default: { |
| 180 | float minVal = |
| 181 | getScalar<float>(reduce_all<af_min_t, float, float>(supEdges)); |
| 182 | auto normG = normalize(supEdges, minVal, maxVal); |
| 183 | auto T2 = createValueArray<float>(supEdges.dims(), t2); |
| 184 | auto T1 = createValueArray<float>(supEdges.dims(), t1); |
| 185 | Array<char> weak1 = |
| 186 | logicOp<float, af_ge_t>(normG, T1, normG.dims()); |
| 187 | Array<char> weak2 = |
| 188 | logicOp<float, af_lt_t>(normG, T2, normG.dims()); |
| 189 | Array<char> weak = |
| 190 | logicOp<char, af_and_t>(weak1, weak2, weak1.dims()); |
| 191 | Array<char> strong = |
| 192 | logicOp<float, af_ge_t>(normG, T2, normG.dims()); |
| 193 | return std::make_pair(strong, weak); |
| 194 | }; |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | template<typename T> |
| 199 | af_array cannyHelper(const Array<T>& in, const float t1, |
no test coverage detected