Program Listing for File xf_min_max_loc.hpp
↰ Return to documentation for file (/tmp/ws/src/vitis_common/include/core/xf_min_max_loc.hpp
)
/*
* 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_MIN_MAX_LOC_HPP_
#define _XF_MIN_MAX_LOC_HPP_
#ifndef __cplusplus
#error C++ is needed to include this header
#endif
#include "hls_stream.h"
#include "../common/xf_common.hpp"
namespace xf {
namespace cv {
template <int SRC_T, int ROWS, int COLS, int DEPTH, int NPC, int WORDWIDTH, int COL_TRIP>
void xFMinMaxLocKernel(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& _src,
int& _minval1,
int& _maxval1,
unsigned short int& _minlocx,
unsigned short int& _minlocy,
unsigned short int& _maxlocx,
unsigned short int& _maxlocy,
uint16_t height,
uint16_t width) {
// unsigned short int _minlocx,_minlocy, _maxlocx,_maxlocy;
int _minval, _maxval;
ap_uint<13> i, j, k, l, col_ind = 0;
XF_SNAME(WORDWIDTH) val_in;
ap_uint<13> min_loc_tmp_x = 0, min_loc_tmp_y = 0;
uint16_t max_loc_tmp_x = 0, max_loc_tmp_y = 0;
ap_uint<6> step = XF_PIXELDEPTH(DEPTH);
// initializing the minimum location with the maximum possible value
//_minloc.x = ((1 << 16) - 1);
//_minloc.y = ((1 << 16) - 1);
_minlocx = ((1 << 16) - 1);
_minlocy = ((1 << 16) - 1);
// initializing the maximum location with the maximum possible value
// _maxloc.x = ((1 << 16) - 1);
// _maxloc.y = ((1 << 16) - 1);
_maxlocx = ((1 << 16) - 1);
_maxlocy = ((1 << 16) - 1);
// initializing minval with the maximum value
_minval = ((1 << (step - 1)) - 1);
// initializing maxval with the minimum value
_maxval = -(1 << (step - 1));
// temporary arrays to hold the min and max vals
int32_t min_val_tmp[(1 << XF_BITSHIFT(NPC)) + 1], max_val_tmp[(1 << XF_BITSHIFT(NPC)) + 1];
ap_uint<26> min_loc_tmp[(1 << XF_BITSHIFT(NPC)) + 1], max_loc_tmp[(1 << XF_BITSHIFT(NPC)) + 1];
// clang-format off
#pragma HLS ARRAY_PARTITION variable=min_val_tmp complete
#pragma HLS ARRAY_PARTITION variable=max_val_tmp complete
#pragma HLS ARRAY_PARTITION variable=min_loc_tmp complete
#pragma HLS ARRAY_PARTITION variable=max_loc_tmp complete
// clang-format on
// creating an array for minimum and maximum values, depending upon the type of optimization
fillTempBuf:
for (i = 0; i < (1 << XF_BITSHIFT(NPC)); i++) {
// clang-format off
#pragma HLS unroll
// clang-format on
min_val_tmp[i] = ((1 << (step - 1)) - 1);
max_val_tmp[i] = -(1 << (step - 1));
}
rowLoop:
for (i = 0; i < height; i++) {
// clang-format off
#pragma HLS LOOP_TRIPCOUNT min=ROWS max=ROWS
#pragma HLS LOOP_FLATTEN off
// clang-format on
col_ind = 0;
colLoop:
for (j = 0; j < width; j++) {
// clang-format off
#pragma HLS LOOP_TRIPCOUNT min=COL_TRIP max=COL_TRIP
#pragma HLS pipeline
// clang-format on
// reading the data from the stream
val_in = _src.read(i * width + j);
XF_PTNAME(DEPTH) pixel_buf[(1 << XF_BITSHIFT(NPC)) + 1];
// clang-format off
#pragma HLS ARRAY_PARTITION variable=pixel_buf complete dim=1
// clang-format on
ap_uint<9> k = 0;
processLoop:
for (l = 0; l < (1 << XF_BITSHIFT(NPC)); l++) {
// clang-format off
#pragma HLS unroll
// clang-format on
// packing the data from val_in to pixel buffer
pixel_buf[l] = val_in.range(k + (step - 1), k);
if (pixel_buf[l] < min_val_tmp[l]) {
min_val_tmp[l] = pixel_buf[l];
min_loc_tmp[l].range(12, 0) = i;
min_loc_tmp[l].range(25, 13) = col_ind;
}
if (pixel_buf[l] > max_val_tmp[l]) {
max_val_tmp[l] = pixel_buf[l];
max_loc_tmp[l].range(12, 0) = i;
max_loc_tmp[l].range(25, 13) = col_ind;
}
k += step;
// increment if RO and PO cases
if (NPC) {
col_ind++;
}
}
// increment if NO case
if (!NPC) {
col_ind++;
}
}
}
// tracking the minimum and maximum from the resultant min and max buffers
trackLoop:
for (k = 0; k < (1 << XF_BITSHIFT(NPC)); k++) {
// tracking the minimum value and the corresponding location
if (min_val_tmp[k] < _minval) {
_minval = min_val_tmp[k];
_minlocy = /*(uint16_t)*/ (min_loc_tmp[k].range(12, 0));
_minlocx = /*(uint16_t)*/ (min_loc_tmp[k].range(25, 13));
} else if (min_val_tmp[k] <= _minval) {
min_loc_tmp_y = /*(uint16_t)*/ (min_loc_tmp[k].range(12, 0));
min_loc_tmp_x = /*(uint16_t)*/ (min_loc_tmp[k].range(25, 13));
if (min_loc_tmp_y < _minlocy) {
_minval = min_val_tmp[k];
_minlocx = min_loc_tmp_x;
_minlocy = min_loc_tmp_y;
}
else if (min_loc_tmp_y == _minlocy) {
if (min_loc_tmp_x < _minlocx) {
_minval = min_val_tmp[k];
_minlocx = min_loc_tmp_x;
_minlocy = min_loc_tmp_y;
}
}
}
// tracking the maximum value and the corresponding location
if (max_val_tmp[k] > _maxval) {
_maxval = max_val_tmp[k];
_maxlocy = /*(uint16_t)*/ (max_loc_tmp[k].range(12, 0));
_maxlocx = /*(uint16_t)*/ (max_loc_tmp[k].range(25, 13));
} else if (max_val_tmp[k] >= _maxval) {
max_loc_tmp_y = (uint16_t)(max_loc_tmp[k].range(12, 0));
max_loc_tmp_x = (uint16_t)(max_loc_tmp[k].range(25, 13));
if (max_loc_tmp_y < _maxlocy) {
_maxval = max_val_tmp[k];
_maxlocx = max_loc_tmp_x;
_maxlocy = max_loc_tmp_y;
}
else if (max_loc_tmp_y == _maxlocy) {
if (max_loc_tmp_x < _maxlocx) {
_maxval = max_val_tmp[k];
_maxlocx = max_loc_tmp_x;
_maxlocy = max_loc_tmp_y;
}
}
}
}
_minval1 = _minval;
_maxval1 = _maxval;
}
template <int SRC_T, int ROWS, int COLS, int NPC = 0>
void minMaxLoc(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& _src,
int32_t* min_value,
int32_t* max_value,
uint16_t* _minlocx,
uint16_t* _minlocy,
uint16_t* _maxlocx,
uint16_t* _maxlocy) {
#ifndef __SYNTHESIS__
assert(((NPC == XF_NPPC1) || (NPC == XF_NPPC8)) && "NPC must be XF_NPPC1, XF_NPPC8 or XF_NPPC16");
assert(((_src.rows <= ROWS) && (_src.cols <= COLS)) && "ROWS and COLS should be greater than input image");
#endif
// clang-format off
#pragma HLS inline off
// clang-format on
uint16_t _min_locx, _min_locy, _max_locx, _max_locy;
int32_t _min_val, _max_val;
uint16_t height = _src.rows;
uint16_t width = _src.cols >> XF_BITSHIFT(NPC);
xFMinMaxLocKernel<SRC_T, ROWS, COLS, XF_DEPTH(SRC_T, NPC), NPC, XF_WORDWIDTH(SRC_T, NPC),
(COLS >> XF_BITSHIFT(NPC))>(_src, _min_val, _max_val, _min_locx, _min_locy, _max_locx, _max_locy,
height, width);
*min_value = _min_val;
*max_value = _max_val;
*_minlocx = _min_locx;
*_minlocy = _min_locy;
*_maxlocx = _max_locx;
*_maxlocy = _max_locy;
}
} // namespace cv
} // namespace xf
#endif