.. _program_listing_file__tmp_ws_src_vitis_common_include_imgproc_xf_otsuthreshold.hpp: Program Listing for File xf_otsuthreshold.hpp ============================================= |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/vitis_common/include/imgproc/xf_otsuthreshold.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * Copyright 2019 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _XF_OTSUTHRESHOLD_HPP_ #define _XF_OTSUTHRESHOLD_HPP_ #include "../common/xf_types.hpp" #include "../core/xf_math.h" #include "xf_histogram.hpp" namespace xf { namespace cv { static void xfOtsuKernel(uint32_t _hist[0][256], uint16_t _height, uint16_t _width, uint8_t& thresh) { // clang-format off #pragma HLS INLINE off // clang-format on ap_uint<33> HistArray[256] = {0}; ap_uint<45> tmp1, tmp2; ap_uint<25> total; uint8_t max_val = 0; unsigned int sum = 0; unsigned short int cols = _width; unsigned short int rows = _height; char shift1 = 0, shift2 = 0; char shift3, shift4; unsigned int wB = 0; unsigned int wF = 0; unsigned long long int sumB = 0; unsigned long long int varMax = 0; unsigned int wdt = xf::cv::Inverse(cols, 16, &shift1); // Q0.24 unsigned int hgt = xf::cv::Inverse(rows, 16, &shift2); // Q0.24 char n1, n2; if (shift1 > 24) { wdt = wdt >> (shift1 - 24); shift1 = 24; } else if (((shift1 >> 1) << 1) != shift1) { wdt = wdt << (24 - shift1); shift1 = 24; } if (shift2 > 24) { hgt = hgt >> (shift2 - 24); shift2 = 24; } else if (((shift2 >> 1) << 1) != shift2) { hgt = hgt << (24 - shift2); shift2 = 24; } shift3 = shift1 >> 1; shift4 = shift2 >> 1; tmp1 = (cols * wdt) >> shift3; // Q0.12 tmp2 = (rows * hgt) >> shift4; // Q0.12 total = tmp1 * tmp2; // Q0.25 HISTOGRAM_NORM_LOOP: for (uint16_t i = 0; i < 256; i++) { // clang-format off #pragma HLS PIPELINE // clang-format on tmp1 = (ap_uint<45>)_hist[0][i]; tmp2 = (tmp1 * wdt) >> shift3; HistArray[i] = (tmp2 * hgt) >> shift4; // Histogram array is expressed in Q8.25 } SUM_LOOP: for (uint16_t i = 0; i < 256; i++) { // clang-format off #pragma HLS PIPELINE // clang-format on sum = sum + i * HistArray[i]; // sum is expressed in Q8.24 } THRESHOLD_LOOP: for (uint16_t i = 0; i < 256; i++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=256 max=256 #pragma HLS PIPELINE // clang-format on wB = wB + HistArray[i]; // wB is expressed in Q0.25 if (wB > 0) { if ((wB >> (shift3 + shift4)) == 1) break; wF = total - wB; // wF is expressed in Q0.25 sumB = sumB + HistArray[i] * i; // sumB is expressed in Q8.24 unsigned int b = (wF + wB); // b is expressed in Q0.25 long long int a1 = (sumB * b) >> (shift3 + shift4); // a1 is expressed in Q8.25 long long int c1 = ((long long int)sum * wB) >> (shift3 + shift4); // c1 is expressed in Q8.25 long long int d = a1 - c1; d = __ABS(d); unsigned int res = (d * d) >> (shift3 + shift4 + 10); // res is expressed in Q16.16 unsigned short int x_inv1 = (unsigned short int)(wB >> 9); unsigned short int x_inv2 = (unsigned short int)(wF >> 9); unsigned int val1 = xf::cv::Inverse(x_inv1, 0, &n1); unsigned int val2 = xf::cv::Inverse(x_inv2, 0, &n2); unsigned long long int maxtmp = (unsigned long long int)((unsigned long long int)res * (unsigned long long int)val1) >> n1; unsigned long long max = (maxtmp * (unsigned long long)val2) >> n2; if (max > varMax) { varMax = max; max_val = i; } } } thresh = max_val; } /********************************************************************* * Otsuthreshold : Computes the otsu threshold for the input image *********************************************************************/ template void OtsuThreshold(xf::cv::Mat& _src_mat, uint8_t& _thresh) { #ifndef __SYNTHESIS__ assert(((NPC == XF_NPPC1) || (NPC == XF_NPPC8)) && "NPC must be XF_NPPC1, XF_NPPC8 "); assert(((_src_mat.rows <= ROWS) && (_src_mat.cols <= COLS)) && "ROWS and COLS should be greater than input image"); #endif uint32_t hist[XF_CHANNELS(SRC_T, NPC)][256]; uint8_t thresh; // clang-format off #pragma HLS INLINE off #pragma HLS interface ap_fifo port=hist // clang-format on uint16_t width = _src_mat.cols >> (XF_BITSHIFT(NPC)); uint16_t height = _src_mat.rows; xFHistogramKernel> (XF_BITSHIFT(NPC))) >> 1), XF_CHANNELS(SRC_T, NPC)>(_src_mat, hist, height, width); xfOtsuKernel(hist, height, _src_mat.cols, thresh); _thresh = thresh; } } // namespace cv } // namespace xf #endif //