Program Listing for File xf_corner_update.hpp
↰ Return to documentation for file (/tmp/ws/src/vitis_common/include/imgproc/xf_corner_update.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_CORNER_UPDATE_HPP__
#define __XF_CORNER_UPDATE_HPP__
#include "ap_int.h"
#include "hls_stream.h"
#include "../common/xf_common.hpp"
#include "../common/xf_utility.hpp"
namespace xf {
namespace cv {
template <unsigned int MAXCORNERSNO, unsigned int TYPE, unsigned int ROWS, unsigned int COLS, unsigned int NPC>
void cornerUpdate(unsigned long* list_fix,
unsigned int* list,
uint32_t nCorners,
xf::cv::Mat<TYPE, ROWS, COLS, NPC>& flow_vectors,
ap_uint<1> harris_flag) {
unsigned int* flowvectorsDataPtr = (unsigned int*)flow_vectors.data;
unsigned int list_flag_tmp;
unsigned int row_num_fix = 0;
unsigned int col_num_fix = 0;
unsigned short row_num;
unsigned short col_num;
// reading the packed flow vectors
unsigned int flowuv_tl;
unsigned int flowuv_tr;
unsigned int flowuv_bl;
unsigned int flowuv_br;
for (int li = 0; li < nCorners; li++) {
// clang-format off
#pragma HLS LOOP_TRIPCOUNT min=1 max=MAXCORNERSNO
// clang-format on
for (int lj = 0; lj < 6; lj++) {
// clang-format off
#pragma HLS PIPELINE II=1
// clang-format on
if (lj == 0) {
unsigned int point = list[li];
unsigned long list_flag_data = list_fix[li];
if (harris_flag) {
// unsigned int point = list[li];
// unsigned long list_flag_data = list_fix[li];
list_flag_tmp = ((unsigned long)list_flag_data & 0xFFFFFC0000000000) >> 42; //.range(63,42);
// row_num_fix and col_num_fix in Q16.0 format, but the format is converted to Q16.5
if (list_flag_tmp == 0) {
row_num_fix = ((point >> 16) & (0x0000FFFF)) << 5; //((ap_uint<21>)point.range(31,16))<<5;
col_num_fix = ((point) & (0x0000FFFF)) << 5; //((ap_uint<21>)point.range(15,0))<<5;
list_flag_tmp = ((unsigned long)list_flag_data & 0xFFFFFC0000000000) >> 42; //.range(63,42);
}
} else {
// unsigned long list_flag_data = list_fix[li];
// row_num_fix and col_num_fix in Q16.5 format
list_flag_tmp = ((unsigned long)list_flag_data & 0xFFFFFC0000000000) >> 42; //.range(63,42);
if (list_flag_tmp == 0) {
row_num_fix = ((list_flag_data >> 21) & (0x001FFFFF)); //(ap_uint<21>)point.range(41,21);
col_num_fix = ((list_flag_data) & (0x001FFFFF)); //((a(ap_uint<21>)point.range(20,0);
}
}
row_num = (unsigned short)(row_num_fix >> 5);
col_num = (unsigned short)(col_num_fix >> 5);
} else if (lj == 1) {
flowuv_tl = flowvectorsDataPtr[row_num * (flow_vectors.cols) + col_num];
} else if (lj == 2) {
flowuv_tr = flowvectorsDataPtr[row_num * (flow_vectors.cols) + (col_num + 1)];
} else if (lj == 3) {
flowuv_bl = flowvectorsDataPtr[(row_num + 1) * (flow_vectors.cols) + col_num];
} else if (lj == 4) {
flowuv_br = flowvectorsDataPtr[(row_num + 1) * (flow_vectors.cols) + (col_num + 1)];
} else if (lj == 5) {
unsigned int rl_fix = ((row_num_fix >> 5) << 5);
unsigned int ct_fix = ((col_num_fix >> 5) << 5);
unsigned int rr_fix = rl_fix + 32;
unsigned int cb_fix = ct_fix + 32;
// Q0.5*Q0.5 -> Q0.10 >> 5 -> Q0.5
unsigned short tl_w = ((rr_fix - row_num_fix) * (cb_fix - col_num_fix)) >> 5;
unsigned short tr_w = ((row_num_fix - rl_fix) * (cb_fix - col_num_fix)) >> 5;
unsigned short bl_w = ((rr_fix - row_num_fix) * (col_num_fix - ct_fix)) >> 5;
unsigned short br_w = ((row_num_fix - rl_fix) * (col_num_fix - ct_fix)) >> 5;
// extracting the flow vectors, format A10.6
short flow_utl = (flowuv_tl >> 16);
short flow_vtl = (0x0000FFFF & flowuv_tl);
short flow_utr = (flowuv_tr >> 16);
short flow_vtr = (0x0000FFFF & flowuv_tr);
short flow_ubl = (flowuv_bl >> 16);
short flow_vbl = (0x0000FFFF & flowuv_bl);
short flow_ubr = (flowuv_br >> 16);
short flow_vbr = (0x0000FFFF & flowuv_br);
short flow_u = ((tl_w * flow_utl) + (tr_w * flow_utr) + (bl_w * flow_ubl) + (br_w * flow_ubr)) >> 6;
short flow_v = ((tl_w * flow_vtl) + (tr_w * flow_vtr) + (bl_w * flow_vbl) + (br_w * flow_vbr)) >> 6;
// add the flow vector to the corner data, rx and ry in Q16.5 format // TODO: check the
// overflow/underflow
unsigned int rx = (unsigned int)flow_u + (unsigned int)col_num_fix;
unsigned int ry = (unsigned int)flow_v + (unsigned int)row_num_fix;
unsigned long outpoint_fix = 0;
unsigned int outpoint = 0;
if ((ry < (flow_vectors.rows << 5)) && (ry >= 0) && (rx >= 0) && (rx < (flow_vectors.cols << 5)) &&
(list_flag_tmp == 0)) {
outpoint_fix =
((unsigned long)ry << 21 & 0x000003FFFFE00000) | ((unsigned long)rx & 0x00000000001FFFFF);
// outpoint_fix.range(20,0) = (ap_uint<21>)rx;
// outpoint_fix.range(41,21) = (ap_uint<21>)ry;
// outpoint_fix.range(20,0) = (ap_uint<21>)rx;
outpoint = ((unsigned int)((ry + 16) >> 5) << 16 & 0xFFFF0000) |
((unsigned int)((rx + 16) >> 5) & 0x0000FFFF);
// outpoint.range(31,16) = (ry+16)>>5; // rounding-off by adding 0.5 and flooring
// outpoint.range(15,0) = (rx+16)>>5;
} else {
outpoint_fix = (unsigned long)1 << 42 & 0xFFFFFC0000000000;
}
list[li] = outpoint;
list_fix[li] = outpoint_fix;
}
}
}
}
} // namespace cv
} // namespace xf
#endif