.. _program_listing_file__tmp_ws_src_vitis_common_include_imgproc_xf_erosion.hpp: Program Listing for File xf_erosion.hpp ======================================= |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/vitis_common/include/imgproc/xf_erosion.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_MEDIAN_BLUR_ #define _XF_MEDIAN_BLUR_ #include "ap_int.h" #include "hls_stream.h" #include "../common/xf_common.hpp" #include "../common/xf_utility.hpp" namespace xf { namespace cv { template void function_apply(XF_PTUNAME(DEPTH) * OutputValue, XF_PTUNAME(DEPTH) src_buf[K_ROWS][K_COLS], unsigned char kernel[K_ROWS][K_COLS]) { // clang-format off #pragma HLS INLINE // clang-format on XF_PTUNAME(DEPTH) packed_val = 0, depth = XF_PIXELWIDTH(DEPTH, XF_NPPC1) / PLANES; Apply_dilate_Loop: for (ap_uint<5> c = 0, k = 0; c < PLANES; c++, k += depth) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=PLANES #pragma HLS UNROLL // clang-format on XF_PTNAME(DEPTH) max = 255; for (ap_uint<13> k_rows = 0; k_rows < K_ROWS; k_rows++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS #pragma HLS UNROLL // clang-format on for (ap_uint<13> k_cols = 0; k_cols < K_COLS; k_cols++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_COLS #pragma HLS UNROLL // clang-format on if (kernel[k_rows][k_cols]) { if (src_buf[k_rows][k_cols].range(k + (depth - 1), k) < max) { max = src_buf[k_rows][k_cols].range(k + (depth - 1), k); } } } } packed_val.range(k + (depth - 1), k) = max; } *OutputValue = packed_val; return; } template void Process_function(xf::cv::Mat& _src_mat, unsigned char kernel[K_ROWS][K_COLS], xf::cv::Mat& _out_mat, XF_TNAME(TYPE, NPC) buf[K_ROWS][(COLS >> XF_BITSHIFT(NPC))], XF_PTUNAME(TYPE) src_buf[K_ROWS][XF_NPIXPERCYCLE(NPC) + (K_COLS - 1)], XF_TNAME(TYPE, NPC) & P0, uint16_t img_width, uint16_t img_height, uint16_t& shift_x, ap_uint<13> row_ind[K_ROWS], ap_uint<13> row, int& rd_ind, int& wr_ind) { // clang-format off #pragma HLS INLINE // clang-format on XF_TNAME(TYPE, NPC) buf_cop[K_ROWS]; XF_PTUNAME(TYPE) OutputValue; // clang-format off #pragma HLS ARRAY_PARTITION variable=buf_cop complete dim=1 // clang-format on uint16_t npc = XF_NPIXPERCYCLE(NPC); uint16_t col_loop_var = (((K_COLS >> 1) + (npc - 1)) / npc); for (int k_row = 0; k_row < K_ROWS; k_row++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS #pragma HLS unroll // clang-format on for (int k_col = 0; k_col < (npc + K_COLS - 1); k_col++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_COLS #pragma HLS unroll // clang-format on src_buf[k_row][k_col] = 0; src_buf[k_row][k_col].b_not(); //-1; } } Col_Loop: for (ap_uint<13> col = 0; col < ((img_width) >> XF_BITSHIFT(NPC)) + col_loop_var; col++) // Image width should be multiple of NPC { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=TC #pragma HLS pipeline #pragma HLS LOOP_FLATTEN OFF // clang-format on if (col < (img_width >> XF_BITSHIFT(NPC))) { if (row < img_height) { buf[row_ind[K_ROWS - 1]][col] = _src_mat.read(rd_ind); // Read data rd_ind++; } else { buf[row_ind[K_ROWS - 1]][col] = 0; //-1; buf[row_ind[K_ROWS - 1]][col].b_not(); } } for (int idx = 0; idx < K_ROWS; idx++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=K_ROWS max=K_ROWS #pragma HLS UNROLL // clang-format on if (col < (img_width >> XF_BITSHIFT(NPC))) buf_cop[idx] = buf[(row_ind[idx])][col]; else { buf_cop[idx] = 0; // buf_cop[idx]; buf_cop[idx].b_not(); } } XF_PTUNAME(TYPE) src_buf_temp_copy[K_ROWS][XF_NPIXPERCYCLE(NPC)]; XF_PTUNAME(TYPE) src_buf_temp_copy_extract[XF_NPIXPERCYCLE(NPC)]; for (int extract_px = 0; extract_px < K_ROWS; extract_px++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS #pragma HLS unroll // clang-format on xfExtractPixels(src_buf_temp_copy_extract, buf_cop[extract_px], 0); for (int ext_copy = 0; ext_copy < npc; ext_copy++) { // clang-format off #pragma HLS unroll // clang-format on src_buf[extract_px][(K_COLS - 1) + ext_copy] = src_buf_temp_copy_extract[ext_copy]; } } XF_PTUNAME(TYPE) src_buf_temp_med_apply[K_ROWS][K_COLS]; XF_PTUNAME(TYPE) OutputValues[XF_NPIXPERCYCLE(NPC)]; for (int iter = 0; iter < npc; iter++) { // clang-format off #pragma HLS pipeline // clang-format on for (int copyi = 0; copyi < K_ROWS; copyi++) { for (int copyj = 0; copyj < K_COLS; copyj++) { src_buf_temp_med_apply[copyi][copyj] = src_buf[copyi][copyj + iter]; } } function_apply(&OutputValue, src_buf_temp_med_apply, kernel); // processing 8-pixels OutputValues[iter] = OutputValue; } int start_write = (((K_COLS >> 1) + (npc - 1)) / npc); if (NPC == XF_NPPC8) { if (col == 0) { shift_x = 0; P0 = 0; xfPackPixels(&OutputValues[0], P0, (K_COLS >> 1), (npc - (K_COLS >> 1)), shift_x); } else { xfPackPixels(&OutputValues[0], P0, 0, (K_COLS >> 1), shift_x); _out_mat.write(wr_ind, P0); shift_x = 0; P0 = 0; xfPackPixels(&OutputValues[0], P0, (K_COLS >> 1), (npc - (K_COLS >> 1)), shift_x); wr_ind++; } } if (NPC == XF_NPPC1) { if (col >= start_write) { _out_mat.write(wr_ind, OutputValue); wr_ind++; } } for (ap_uint<13> extract_px = 0; extract_px < K_ROWS; extract_px++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=K_ROWS max=K_ROWS // clang-format on for (ap_uint<13> col_warp = 0; col_warp < (K_COLS - 1); col_warp++) { // clang-format off #pragma HLS UNROLL #pragma HLS LOOP_TRIPCOUNT min=K_COLS max=K_COLS // clang-format on src_buf[extract_px][col_warp] = src_buf[extract_px][col_warp + npc]; // Shifting the 2 colums of src_buf to process next pixel } } } // Col_Loop } // end of processDilate template void xferode(xf::cv::Mat& _src, xf::cv::Mat& _dst, uint16_t img_height, uint16_t img_width, unsigned char kernel[K_ROWS][K_COLS]) { ap_uint<13> row_ind[K_ROWS]; // clang-format off #pragma HLS ARRAY_PARTITION variable=row_ind complete dim=1 // clang-format on uint16_t shift_x = 0; ap_uint<13> row, col; XF_PTUNAME(TYPE) src_buf[K_ROWS][XF_NPIXPERCYCLE(NPC) + (K_COLS - 1)]; // clang-format off #pragma HLS ARRAY_PARTITION variable=src_buf complete dim=1 #pragma HLS ARRAY_PARTITION variable=src_buf complete dim=2 // clang-format on XF_TNAME(TYPE, NPC) P0; XF_TNAME(TYPE, NPC) buf[K_ROWS][(COLS >> XF_BITSHIFT(NPC))]; // clang-format off #pragma HLS RESOURCE variable=buf core=RAM_S2P_BRAM #pragma HLS ARRAY_PARTITION variable=buf complete dim=1 // clang-format on // initializing row index for (int init_row_ind = 0; init_row_ind < K_ROWS; init_row_ind++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS // clang-format on row_ind[init_row_ind] = init_row_ind; } int rd_ind = 0; // Reading the first row of image and initializing the buf read_lines: for (ap_uint<13> i_row = (K_ROWS >> 1); i_row < (K_ROWS - 1); i_row++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS // clang-format on for (ap_uint<13> i_col = 0; i_col> XF_BITSHIFT(NPC); i_col++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=TC/NPC #pragma HLS pipeline #pragma HLS LOOP_FLATTEN OFF // clang-format on buf[i_row][i_col] = _src.read(rd_ind); // data[rd_ind];//reading the rows of image rd_ind++; } } // takes care of top borders ( intializing them with first row of image) init_boarder: for (ap_uint<13> i_row = 0; i_row> 1; i_row++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS // clang-format on for (ap_uint<13> i_col = 0; i_col> XF_BITSHIFT(NPC); i_col++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=TC/NPC #pragma HLS UNROLL // clang-format on buf[i_row][i_col] = -1; // buf[K_ROWS>>1][i_col]; } } int wr_ind = 0; Row_Loop: for (row = (K_ROWS >> 1); row < img_height + (K_ROWS >> 1); row++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=ROWS // clang-format on P0 = 0; Process_function( _src, kernel, _dst, buf, src_buf, P0, img_width, img_height, shift_x, row_ind, row, rd_ind, wr_ind); // update indices (by cyclic shifting ) ap_uint<13> zero_ind = row_ind[0]; for (ap_uint<13> init_row_ind = 0; init_row_ind < K_ROWS - 1; init_row_ind++) { // clang-format off #pragma HLS LOOP_TRIPCOUNT min=1 max=K_ROWS #pragma HLS UNROLL // clang-format on row_ind[init_row_ind] = row_ind[init_row_ind + 1]; } row_ind[K_ROWS - 1] = zero_ind; } // Row_Loop } template void erode(xf::cv::Mat& _src, xf::cv::Mat& _dst, unsigned char _kernel[K_ROWS * K_COLS]) { // clang-format off #pragma HLS INLINE OFF // clang-format on unsigned short imgheight = _src.rows; unsigned short imgwidth = _src.cols; #ifndef __SYNTHESIS__ assert(BORDER_TYPE == XF_BORDER_CONSTANT && "Only XF_BORDER_CONSTANT is supported"); assert(((imgheight <= ROWS) && (imgwidth <= COLS)) && "ROWS and COLS should be greater than input image"); #endif if (K_SHAPE == XF_SHAPE_RECT) // iterations >1 is not supported for ELLIPSE and CROSS { #define NEW_K_ROWS (K_ROWS + ((ITERATIONS - 1) * (K_ROWS - 1))) #define NEW_K_COLS (K_COLS + ((ITERATIONS - 1) * (K_COLS - 1))) unsigned char kernel_new[NEW_K_ROWS][NEW_K_COLS]; // clang-format off #pragma HLS array_partition variable=kernel_new dim=0 // clang-format on for (unsigned char i = 0; i < NEW_K_ROWS; i++) { for (unsigned char j = 0; j < NEW_K_COLS; j++) { kernel_new[i][j] = 1; // _kernel[i*NEW_K_COLS+j]; } } xferode> XF_BITSHIFT(NPC)) + (NEW_K_ROWS >> 1), NEW_K_ROWS, NEW_K_COLS>(_src, _dst, imgheight, imgwidth, kernel_new); } else { unsigned char kernel[K_ROWS][K_COLS]; // clang-format off #pragma HLS array_partition variable=kernel complete dim=0 // clang-format on for (unsigned char i = 0; i < K_ROWS; i++) { for (unsigned char j = 0; j < K_COLS; j++) { kernel[i][j] = _kernel[i * K_COLS + j]; } } xferode> XF_BITSHIFT(NPC)) + (K_COLS >> 1), K_ROWS, K_COLS>(_src, _dst, imgheight, imgwidth, kernel); } return; } // erode } // namespace cv } // namespace xf #endif