.. _program_listing_file__tmp_ws_src_vitis_common_include_imgproc_xf_hog_descriptor_compute_hist.hpp: Program Listing for File xf_hog_descriptor_compute_hist.hpp =========================================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/vitis_common/include/imgproc/xf_hog_descriptor_compute_hist.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_HOG_DESCRIPTOR_COMPUTE_HIST_HPP_ #define _XF_HOG_DESCRIPTOR_COMPUTE_HIST_HPP_ #ifndef __cplusplus #error C++ is needed to include this header #endif #include "xf_hog_descriptor_utility.hpp" /************************************************************************* * Macros for the histogram function *************************************************************************/ #define XF_HOG_1_BY_20 3276 // considering the Bin stride as 20 // in Q0.16 format #define XF_HOG_PI 23040 // 180 in Q8.7 format // functional macro to scale the angle to 180 #define scale_to_PI(a) \ if (a > XF_HOG_PI) a = a - XF_HOG_PI /*************************************************************************/ /*************************************************************************** * xFDHOGbilinearNO *************************************************************************** * functionality: utility function for the compute histogram kernel. * * -> performs bilinear interpolation on the magnitude depending upon * the phase value and the bin position where the pixel falls under * * -> p: input phase value (Q9.7) * * -> m: input magnitude value (Q9.7) * * -> bin_center: bin center array which acts as a LUT to fetch the * corresponding bin centers * * -> bin: temporary array to hold the histogram * ***************************************************************************/ template void xFDHOGbilinearNO(XF_PTNAME(DEPTH) p, XF_PTNAME(DEPTH) m, uint16_t* bin_center, hist_type* bin) { // clang-format off #pragma HLS INLINE OFF // clang-format on // finding the bin index with respect to the phase uint32_t tmp_bin_idx = p * XF_HOG_1_BY_20; // Q9.7xQ0.16 -> Q9.23 uchar_t bin_idx = tmp_bin_idx >> 23; uchar_t index_1, index_2; // magnitude factor // uint32_t mag_factor = (uint16_t)XF_1_BY_20 * m; // Q9.16 format uint32_t mag_factor = m * XF_HOG_1_BY_20; // Q9.7xQ0.16 -> Q9.23 uint16_t frac = 0; // interpolate with the previous cell, when 'p' is less than bin_center if (p < bin_center[bin_idx]) { /* when the bin is the first bin and the 'p' is less than the corresponding bin_center value then interpolate with the last cell (in a circular fashion) */ if (bin_idx == 0) { frac = (p - (bin_center[bin_idx] - BIN_STRIDE_FIX)); index_1 = bin_idx; index_2 = (NOB - 1); } else { frac = (p - bin_center[bin_idx - 1]); index_1 = bin_idx; index_2 = (bin_idx - 1); } } // interpolate with the next cell, when 'p' is greater than bin_center else { /* when the bin is the last bin and the 'p' is greater than the corresponding bin_center value then interpolate with the first cell (in a circular fashion) */ if (bin_idx == (NOB - 1)) { frac = ((bin_center[bin_idx] + BIN_STRIDE_FIX) - p); index_1 = bin_idx; index_2 = 0; } else { frac = (bin_center[bin_idx + 1] - p); index_1 = bin_idx; index_2 = (bin_idx + 1); } } // interpolate to the bin according to the fraction values // frac -> Q9.7 format hist_type part_1 = (hist_type)(((ap_uint<40>)frac * (ap_uint<40>)mag_factor) >> 22); // Q9.7xQ9.23 -> Q18.30>>22 -> Q18.8 format uint32_t m_shifted = (uint32_t)m << 1; // converting 'm' to Q9.8 format hist_type part_2 = (hist_type)(m_shifted - part_1); // Q9.8 format // accumulate the data to bin array [ bin array in Q9.8 format ] bin[index_1] += part_1; bin[index_2] += part_2; } /*************************************************************************************** * xFDHOGcomputeHistNO *************************************************************************************** * functionality: utility function for the compute histogram kernel. * * -> performs binning of the interpolated values into the histogram * array * * -> bin : array containing the bin values that need to be accumulated * into the HA array * * -> HA : the histogram array that need to be accumulated * * -> ssv : sum of squared value (square all the 9 bins and accumulate then). * This value acts as a temporary result for normalization factor. * **************************************************************************************/ template void xFDHOGcomputeHistNO(hls::stream& _phase_strm, hls::stream& _mag_strm, hist_type HA[][NOB], ssv_type* ssv, uint16_t* bin_center, uint16_t nohc) { // read the input data from the streams to the local variables XF_SNAME(WORDWIDTH) phase_data, mag_data; XF_PTNAME(DEPTH) p, m; uint16_t proc_loop = XF_WORDDEPTH(WORDWIDTH), frac; uchar_t step = XF_PIXELDEPTH(DEPTH), bin_idx = 0; ap_uint<16> i, j, r; ap_uint<8> k; // NPC copied of the histogram array hist_type bin[NOB]; // clang-format off #pragma HLS ARRAY_PARTITION variable=bin complete dim=1 // clang-format on // initializing the histogram array with zero loop_i_init_zero: for (i = 0; i < nohc; i++) { // clang-format off #pragma HLS PIPELINE // clang-format on loop_j_init_zero: for (j = 0; j < NOB; j++) { // clang-format off #pragma HLS unroll // clang-format on HA[i][j] = 0; } } cell_height_loop: for (i = 0; i < CELL_HEIGHT; i++) { no_of_horz_cell_loop: for (r = 0; r < nohc; r++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=NOHC max=NOHC #pragma HLS PIPELINE // clang-format on init_bin_loop_k: for (k = 0; k < NOB; k++) { // clang-format off #pragma HLS unroll // clang-format on bin[k] = 0; } img_col_loop: for (j = 0; j < CELL_WIDTH; j++) { // reading data from the stream phase_data = _phase_strm.read(); mag_data = _mag_strm.read(); p = phase_data.range((step - 1), 0); m = mag_data.range((step - 1), 0); // scale the angle to 180 degree (if it is beyond 180) scale_to_PI(p); // accumulating to the temporary histogram array 'bin' xFDHOGbilinearNO(p, m, bin_center, bin); } hist_BRAM_updation_loop: for (k = 0; k < NOB; k++) { HA[r][k] += bin[k]; // HA array in Q15.8 format } // square computation on temporary ssv val ssv_type tmp = 0; tmp_ssv_computation: for (k = 0; k < NOB; k++) // adder tree inferred { // clang-format off #pragma HLS unroll // clang-format on tmp += (HA[r][k] * HA[r][k]); } ssv[r] = tmp; // Q29.16 format <45> bits } } } /*************************************************************************** * xFDHOGbilinearRO *************************************************************************** * functionality: utility function for the compute histogram kernel. * * -> performs bilinear interpolation on the magnitude depending upon * the phase value and the bin position where the pixel falls under * * -> index : these variables indicates the bins on which the * particular pixel falls under * * -> part : these variables contains the splitted up magnitude data * ***************************************************************************/ template void xFDHOGbilinearRO(XF_PTNAME(DEPTH) p, XF_PTNAME(DEPTH) m, uint16_t* bin_center, uchar_t* index_1, uchar_t* index_2, hist_type* part_1, hist_type* part_2) { // clang-format off #pragma HLS INLINE OFF // clang-format on // finding the bin index with respect to the phase uint32_t tmp_bin_idx = p * (uint16_t)XF_HOG_1_BY_20; uchar_t bin_idx = tmp_bin_idx >> 16; // magnitude factor uint32_t mag_factor = (uint16_t)XF_HOG_1_BY_20 * m; uint16_t frac = 0; // interpolate with the previous cell, when 'p' is less than bin_center if (p < bin_center[bin_idx]) { /* when the bin is the first bin and the 'p' is less than the corresponding bin_center value then interpolate with the last cell (in a circular fashion) */ if (bin_idx == 0) { frac = (p - (bin_center[bin_idx] - BIN_STRIDE)); *index_1 = bin_idx; *index_2 = (NOB - 1); } else { frac = (p - bin_center[bin_idx - 1]); *index_1 = bin_idx; *index_2 = (bin_idx - 1); } } // interpolate with the next cell, when 'p' is greater than bin_center else { /* when the bin is the last bin and the 'p' is greater than the corresponding bin_center value then interpolate with the first cell (in a circular fashion) */ if (bin_idx == (NOB - 1)) { frac = ((bin_center[bin_idx] + BIN_STRIDE) - p); *index_1 = bin_idx; *index_2 = 0; } else { frac = (bin_center[bin_idx + 1] - p); *index_1 = bin_idx; *index_2 = (bin_idx + 1); } } // interpolate to the bin according to the fraction values *part_1 = (hist_type)((frac * mag_factor) >> 8); // Q9.8 format uint32_t m_shifted = (uint32_t)m << 8; // converting 'm' to Q9.8 format *part_2 = (hist_type)(m_shifted - *part_1); // Q9.8 format } /*************************************************************************** * xFDHOGBinRO *************************************************************************** * functionality: utility function for the compute histogram kernel to * perform the histogram accumulation. * * -> bin: temporary bin that must be accumulated to HA array * * -> HA : histogram array * * -> j : indicates the cell index * ***************************************************************************/ template void xFDHOGBinRO(hist_type bin[][NOB], hist_type HA[][NOB], uint16_t j) { // clang-format off #pragma HLS INLINE // clang-format on // add all the 8 copies of the temporary array into single copy accumulate_to_bin_0_k: for (uchar_t k = 0; k < NOB; k++) { // clang-format off #pragma HLS UNROLL // clang-format on accumulate_to_bin_0_l: for (uchar_t l = 1; l < (1 << XF_BITSHIFT(NPC)); l++) { bin[0][k] += bin[l][k]; } } // accumulating the temporary histogram to HA array accumulate_HA: for (uchar_t k = 0; k < NOB; k++) { // clang-format off #pragma HLS PIPELINE // clang-format on HA[j][k] += bin[0][k]; } } /*************************************************************************** * xFDHOGcomputeHistRO *************************************************************************** * functionality: kernel function for computing the histogram * * -> compute the histogram with the input phase and the magnitude * values. The output of this function is the computed * histogram array. * * -> _phase_strm: input phase mat object (stream) * _mag_strm : input magnitude mat object (stream) * * -> HA : histogram array (output) * * -> ssv : sum of squared value (output) * * note: This code is disabled for now, and when further develpoment for * higher parallelism is introduced, it will be develped from this code ***************************************************************************/ /*template void xFDHOGcomputeHistRO( auviz::Mat& _phase_strm, auviz::Mat& _mag_strm, hist_type HA[][NOB], ssv_type* ssv, uint16_t* bin_center) { // read the input data from the streams to the local variables XF_SNAME(WORDWIDTH) phase_data, mag_data; XF_PTNAME(DEPTH) p, m; // NPC copied of the histogram array hist_type bin[XF_NPIXPERCYCLE(NPC)][NOB], part_1, part_2; // clang-format off #pragma HLS ARRAY_PARTITION variable=bin complete dim=0 // clang-format on uint16_t proc_loop = XF_WORDDEPTH(WORDWIDTH); uchar_t step = XF_PIXELDEPTH(DEPTH), npc_idx, index_1, index_2; // initializing the histogram array with zero loop_i_init_zero: for(uint16_t i = 0; i < NOHC; i++) { // clang-format off #pragma HLS pipeline // clang-format on loop_j_init_zero: for(uint16_t j = 0; j < NOB; j++) { // clang-format off #pragma HLS unroll // clang-format on HA[i][j] = 0; } } cell_height_loop: for(uint16_t i = 0; i < CELL_HEIGHT; i++) { img_col_loop: for(uint16_t j = 0; j < _phase_strm.cols; j++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=TC max=TC #pragma HLS pipeline // clang-format on // reading data from the stream phase_data = _phase_strm.read(); mag_data = _mag_strm.read(); npc_idx = 0; init_bin_loop_k: for(uchar_t k = 0; k < NOB; k++) { // clang-format off #pragma HLS unroll // clang-format on init_bin_loop_l: for(uchar_t l = 0; l < (1<(p,m,bin_center, &index_1,&index_2,&part_1,&part_2); bin[npc_idx][index_1] = part_1; bin[npc_idx][index_2] = part_2; npc_idx++; } xFDHOGBinRO(bin,HA,j); // HA array will be of format Q15.8 ssv_type tmp_ssv[NOB]; // clang-format off #pragma HLS ARRAY_PARTITION variable=tmp_ssv complete dim=1 // clang-format on // square computation on temporary ssv val for(uchar_t k = 0; k < NOB; k++) { // clang-format off #pragma HLS unroll // clang-format on tmp_ssv[k] = (HA[j][k] * HA[j][k]); } // adder tree for accumulating the array ssv_type var1, var2, var3, var4; var1 = tmp_ssv[0] + tmp_ssv[1]; var2 = tmp_ssv[2] + tmp_ssv[3]; var3 = tmp_ssv[4] + tmp_ssv[5]; var4 = tmp_ssv[6] + tmp_ssv[7]; var1 = var1 + var2; var3 = var3 + var4; var1 = var1 + var3; ssv[j] = var1 + tmp_ssv[8]; // Q29.16 format <45> bits } } }*/ /******************************************************************************************* * xFDHOGcomputeHist ******************************************************************************************* * * functionality: this function acts as a wrapper function for the compute histogram kernel * function. Computed the histogram and the sum of squared value (SSV) * *******************************************************************************************/ template void xFDHOGcomputeHist(hls::stream& _phase_strm, hls::stream& _mag_strm, hist_type HA[][NOB], ssv_type* ssv, uint16_t* bin_center, uint16_t nohc) { // NO mode if (NPC == XF_NPPC1) { xFDHOGcomputeHistNO> XF_BITSHIFT(NPC)), WIN_STRIDE, BIN_STRIDE>(_phase_strm, _mag_strm, HA, ssv, bin_center, nohc); } } #endif // _XF_HOG_DESCRIPTOR_COMPUTE_HIST_HPP_