.. _program_listing_file__tmp_ws_src_vitis_common_include_imgproc_xf_canny.hpp: Program Listing for File xf_canny.hpp ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/vitis_common/include/imgproc/xf_canny.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_CANNY_HPP_ #define _XF_CANNY_HPP_ #ifndef __cplusplus #error C++ is needed to use this file! #endif typedef unsigned short uint16_t; typedef unsigned char uchar; #include "hls_stream.h" #include "../common/xf_common.hpp" #include "../common/xf_utility.hpp" #include "../core/xf_math.h" //#include "xf_sobel.hpp" #include "xf_canny_sobel.hpp" #include "xf_averagegaussianmask.hpp" #include "xf_magnitude.hpp" #include "xf_canny_utils.hpp" namespace xf { namespace cv { template void xFDuplicate_rows(xf::cv::Mat& _src_mat, // hls::stream< XF_SNAME(WORDWIDTH) > &_src_mat, xf::cv::Mat& _src_mat1, xf::cv::Mat& _dst1_mat, xf::cv::Mat& _dst2_mat, xf::cv::Mat& _dst1_out_mat, xf::cv::Mat& _dst2_out_mat, uint16_t img_height, uint16_t img_width) { img_width = img_width >> XF_BITSHIFT(NPC); ap_uint<13> row, col; Row_Loop: for (row = 0; row < img_height; row++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=ROWS max=ROWS #pragma HLS LOOP_FLATTEN off // clang-format on Col_Loop: for (col = 0; col < img_width; col++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=TC max=TC #pragma HLS pipeline // clang-format on XF_SNAME(WORDWIDTH) tmp_src, tmp_src1; tmp_src1 = _src_mat1.read(row * img_width + col); tmp_src = _src_mat.read(row * img_width + col); _dst1_mat.write(row * img_width + col, tmp_src); _dst2_mat.write(row * img_width + col, tmp_src); _dst1_out_mat.write(row * img_width + col, tmp_src1); _dst2_out_mat.write(row * img_width + col, tmp_src1); } } } template void xFPackNMS(xf::cv::Mat& _src_mat, // hls::stream< XF_SNAME(WORDWIDTH_SRC) >& _src_mat, xf::cv::Mat& _dst_mat, // hls::stream< XF_SNAME(WORDWIDTH_DST)>& _dst_mat, uint16_t imgheight, uint16_t imgwidth) { int npcCols = imgwidth; int divNum = (int)(imgwidth / 32); int npcColsNxt = (divNum + 1) * 32; if (imgwidth % 32 != 0) { npcCols = npcColsNxt; } const int num_clks_32pix = 32 / NPC; int col_loop_count_ac = (imgwidth / NPC); int col_loop_count = (npcCols / NPC); // printf("col_loop_count:%d %d \n",col_loop_count_ac,col_loop_count); ap_uint<64> val; int read_ind = 0, write_ind = 0; rowLoop: for (int i = 0; i < (imgheight); i++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=ROWS max=ROWS #pragma HLS LOOP_FLATTEN off // clang-format on colLoop: for (int j = 0; j < col_loop_count; j = j + (num_clks_32pix)) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=COLS/32 max=COLS/32 #pragma HLS pipeline // clang-format on for (int k = 0; k < num_clks_32pix; k++) { // clang-format off #pragma HLS UNROLL // clang-format on if ((j + k) >= col_loop_count_ac) { val.range(k * 2 * NPC + (NPC * 2 - 1), k * 2 * NPC) = 0; //_src_mat.read(read_ind++); } else { val.range(k * 2 * NPC + (NPC * 2 - 1), k * 2 * NPC) = _src_mat.read(read_ind++); } } _dst_mat.write(write_ind++, val); } } } // xFDuplicate_rows template void xFCannyKernel(xf::cv::Mat& _src_mat, xf::cv::Mat& _dst_mat, unsigned char _lowthreshold, unsigned char _highthreshold, uint16_t img_height, uint16_t img_width) { // clang-format off #pragma HLS INLINE OFF // clang-format on // clang-format off #pragma HLS DATAFLOW // clang-format on if (NPC == 8) { xf::cv::Mat gaussian_mat(img_height, img_width); xf::cv::Mat gradx_mat(img_height, img_width); xf::cv::Mat gradx1_mat(img_height, img_width); xf::cv::Mat gradx2_mat(img_height, img_width); xf::cv::Mat grady_mat(img_height, img_width); xf::cv::Mat grady1_mat(img_height, img_width); xf::cv::Mat grady2_mat(img_height, img_width); xf::cv::Mat magnitude_mat(img_height, img_width); xf::cv::Mat phase_mat(img_height, img_width); xf::cv::Mat nms_mat(img_height, img_width); xFAverageGaussianMask3x3> XF_BITSHIFT(NPC))>( _src_mat, gaussian_mat, img_height, img_width); xFSobel( gaussian_mat, gradx_mat, grady_mat, XF_BORDER_REPLICATE, img_height, img_width); xFDuplicate_rows( gradx_mat, grady_mat, gradx1_mat, gradx2_mat, grady1_mat, grady2_mat, img_height, img_width); magnitude(gradx1_mat, grady1_mat, magnitude_mat); xFAngle( gradx2_mat, grady2_mat, phase_mat, img_height, img_width); xFSuppression3x3> XF_BITSHIFT(NPC)), TC2, TC1>( magnitude_mat, phase_mat, nms_mat, _lowthreshold, _highthreshold, img_height, img_width); xFPackNMS( nms_mat, _dst_mat, img_height, img_width); } if (NPC == 1) { xf::cv::Mat gaussian_mat(img_height, img_width); xf::cv::Mat gradx_mat(img_height, img_width); xf::cv::Mat gradx1_mat(img_height, img_width); xf::cv::Mat gradx2_mat(img_height, img_width); xf::cv::Mat grady_mat(img_height, img_width); xf::cv::Mat grady1_mat(img_height, img_width); xf::cv::Mat grady2_mat(img_height, img_width); xf::cv::Mat magnitude_mat(img_height, img_width); xf::cv::Mat phase_mat(img_height, img_width); xf::cv::Mat nms_mat(img_height, img_width); xFAverageGaussianMask3x3> XF_BITSHIFT(NPC))>( _src_mat, gaussian_mat, img_height, img_width); xFSobel( gaussian_mat, gradx_mat, grady_mat, XF_BORDER_REPLICATE, img_height, img_width); xFDuplicate_rows( gradx_mat, grady_mat, gradx1_mat, gradx2_mat, grady1_mat, grady2_mat, img_height, img_width); magnitude(gradx1_mat, grady1_mat, magnitude_mat); xFAngle( gradx2_mat, grady2_mat, phase_mat, img_height, img_width); xFSuppression3x3> XF_BITSHIFT(NPC)), TC2, TC1>(magnitude_mat, phase_mat, nms_mat, _lowthreshold, _highthreshold, img_height, img_width); xFPackNMS( nms_mat, _dst_mat, img_height, img_width); } } /********************************************************************** * xFCanny : Calls the Main Function depends on requirements **********************************************************************/ template void xFCannyEdgeDetector(hls::stream& _src_mat, hls::stream& out_strm, unsigned char _lowthreshold, unsigned char _highthreshold, int _norm_type, uint16_t imgheight, uint16_t imgwidth) { #ifndef __SYNTHESIS__ assert(((_norm_type == XF_L1NORM) || (_norm_type == XF_L2NORM)) && "The _norm_type must be 'XF_L1NORM' or'XF_L2NORM'"); #endif xFCannyKernel> XF_BITSHIFT(NPC)), ((COLS >> XF_BITSHIFT(NPC)) * 3), FILTER_TYPE, USE_URAM>( _src_mat, out_strm, _lowthreshold, _highthreshold, _norm_type, imgheight, imgwidth); } template void Canny(xf::cv::Mat& _src_mat, xf::cv::Mat& _dst_mat, unsigned char _lowthreshold, unsigned char _highthreshold) { // clang-format off #pragma HLS INLINE OFF // clang-format on #ifndef __SYNTHESIS__ assert(((NORM_TYPE == XF_L1NORM) || (NORM_TYPE == XF_L2NORM)) && "The _norm_type must be 'XF_L1NORM' or'XF_L2NORM'"); #endif if (NORM_TYPE == 1) { xFCannyKernel> XF_BITSHIFT(NPC)), 2, ((COLS >> XF_BITSHIFT(NPC)) * 3), FILTER_TYPE, USE_URAM>( _src_mat, _dst_mat, _lowthreshold, _highthreshold, _src_mat.rows, _src_mat.cols); } else { xFCannyKernel> XF_BITSHIFT(NPC)), 2, ((COLS >> XF_BITSHIFT(NPC)) * 3), FILTER_TYPE, USE_URAM>( _src_mat, _dst_mat, _lowthreshold, _highthreshold, _src_mat.rows, _src_mat.cols); } } } // namespace cv } // namespace xf #endif