4.29. tpu_kernel_api_yolov5_out_without_decode
针对1输出的yolov5模型,使用智能视觉深度学习处理器Kernel对后处理进行加速,目前只支持BM1684x,且libsophon的版本必须不低于0.4.6(v23.03.01)。
4.29.1. 构造函数
- 接口形式:
tpu_kernel_api_yolov5_out_without_decode(int device_id, const std::vector<int>& shapes, int network_w=640, int network_h=640, std::string module_file = "/opt/sophon/libsophon-current/lib/tpu_module/libbm1684x_kernel_module.so");
参数说明:
device_id: int
输入参数。使用的设备编号。
shape: std::vector<int>
输入参数。输入数据的shape。
network_w: int
输入参数。模型的输入宽度,默认为640。
network_h: int
输入参数。模型的输入宽度,默认为640。
module_file: string
输入参数。Kernel module文件路径,默认为”/opt/sophon/libsophon-current/lib/tpu_module/libbm1684x_kernel_module.so”。
4.29.2. process
处理接口。
- 接口形式1:
std::vector<std::vector<std::tuple<int, int, int, int ,int, float>>> process( TensorPTRWithName& input, float dete_threshold, float nms_threshold);
参数说明1:
input_data: TensorPTRWithName
输入参数。输入数据,包含一个输出。
dete_threshold: float
输入参数。检测阈值。
nms_threshold: float
输入参数。nms阈值序列。
- 接口形式2:
std::vector<std::vector<std::tuple<int, int, int, int ,int, float>>> process( std::map<std::string, Tensor&>& input, float dete_threshold, float nms_threshold);
参数说明2:
input_data: std::map<std::string, Tensor&>
输入参数。输入数据,包含一个输出。
dete_threshold: float
输入参数。检测阈值。
nms_threshold: float
输入参数。nms阈值序列。
返回值说明:
std::vector<std::vector<std::tuple<left, top, right, bottom, class_id, score> > >
left: int
检测结果最左x坐标。
top: int
检测结果最上y坐标。
right: int
检测结果最右x坐标。
bottom: int
检测结果最下y坐标。
class_id: int
检测结果的类别编号。
score: float
检测结果的分数。
- 示例代码:
#include <sail/cvwrapper.h> #include <sail/tpu_kernel_api.h> #include <opencv2/opencv.hpp> #include <fstream> #include <iostream> #include <vector> #include <string> #include <math.h> using namespace std; void get_ratio(sail::BMImage& bmimg, int& tw, int& th, int& tx1, int& tx2, int& ty1, int& ty2) { int img_w = bmimg.width(); int img_h = bmimg.height(); double r_w = 640.0 / img_w; double r_h = 640.0 / img_h; if (r_h > r_w) { tw = 640; th = static_cast<int>(r_w * img_h); tx1 = tx2 = 0; ty1 = static_cast<int>((640 - th) / 2); ty2 = 640 - th - ty1; } else { tw = static_cast<int>(r_h * img_w); th = 640; tx1 = static_cast<int>((640 - tw) / 2); tx2 = 640 - tw - tx1; ty1 = ty2 = 0; } } int main() { int tpu_id = 0; std::string image_path = "../../../sophon-demo/sample/YOLOv5/datasets/test/3.jpg"; sail::Decoder decoder(image_path, true, tpu_id); std::string bmodel_path = "../../../sophon-demo/sample/YOLOv5/models/BM1684X/yolov5s_v6.1_1output_int8_1b.bmodel"; sail::Handle handle(tpu_id); std::vector<std::pair<float, float>> alpha_beta = {{1.0/255, 0}, {1.0/255, 0}, {1.0/255, 0}}; sail::sail_resize_type resize_type = sail::sail_resize_type::BM_PADDING_TPU_LINEAR; sail::EngineImagePreProcess sail_engineipp(bmodel_path, tpu_id, false); sail_engineipp.InitImagePreProcess(resize_type, true, 10, 10); sail_engineipp.SetPaddingAtrr(114, 114, 114, 1); bool ret1 = sail_engineipp.SetConvertAtrr(alpha_beta); sail::BMImage bm_i; decoder.read(handle, bm_i); decoder.release(); int hw, ratio, txy; get_ratio(bm_i, hw, ratio, txy); bool ret3 = sail_engineipp.PushImage(0, 0, bm_i); std::map<std::string,sail::Tensor*> output_tensor_map ; std::vector<BMImage> ost_images ; std::vector<int> channel_list ; std::vector<int> imageidx_list ; std::vector<std::vector<int>> padding_atrr ; std::tuple<output_tensor_map, ost_images, channel_list ,imageidx_list, padding_atrr>all_out = sail_engineipp.GetBatchData(true); sail::tpu_kernel_api_yolov5_out_without_decode tpu_kernel_1o(0, std::vector<int>{1, 25200, 85}, 640, 640, "/opt/sophon/libsophon-current/lib/tpu_module/libbm1684x_kernel_module.so"); std::vector<std::vector<std::tuple<int, int, int, int ,int, float>>> out_boxs = tpu_kernel_1o->process(output_tensor_map, 0.5, 0.5); std::vector<std::vector<float, 6>> result; for (int bid = 0; bid < out_boxs[0].size(); bid++) { std::vector<float, 6> temp_bbox; temp_bbox[0] = out_boxs[0][bid].class_id; if (temp_bbox[0] == -1)continue; temp_bbox[1] = out_boxs[0][bid].score; temp_bbox[2] = (out_boxs[0][bid].width+ 0.5) / ratio; temp_bbox[3] =(out_boxs[0][bid].height+ 0.5) / ratio; float centerX = ((out_boxs[0][bid].left + out_boxs[0][bid].right) / 2 + 1 - tx1) / ratio - 1; float centerY = ((out_boxs[0][bid].top + out_boxs[0][bid].bottom) / 2 + 1 - ty1) / ratio - 1; temp_bbox[4] = MAX(int(centerX - temp_bbox.width / 2), 0); temp_bbox[5] = MAX(int(centerY - temp_bbox.height / 2), 0); result.push_back(temp_bbox); } }