mdz/paddle/ppyolov5/3_deploy/Deps/modelzoo/modelzoo_utils.hpp

329 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <random>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include <fstream>
#include <random>
#ifdef __linux__
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mman.h>
#include <unistd.h>
#endif
#include "icraft-xir/core/network.h"
#include "icraft-xir/core/data.h"
#include "icraft-xrt/dev/host_device.h"
#include "icraft-xrt/dev/buyi_device.h"
#include "icraft-backends/hostbackend/utils.h"
#include <utils.hpp>
#include <PicPre.hpp>
#include <NetInfo.hpp>
#include <et_device.hpp>
using namespace icraft::xrt;
using namespace icraft::xir;
using namespace std::string_literals;
using namespace std::chrono;
using namespace std::chrono_literals;
std::vector<std::tuple<int, float, cv::Rect2f>> nms_soft(std::vector<int>& id_list, std::vector<float>& socre_list, std::vector<cv::Rect2f>& box_list, float IOU, int max_nms = 3000) {
std::vector<std::tuple<int, float, cv::Rect2f>> filter_res;
std::vector<std::tuple<int, float, cv::Rect2f>> nms_res;
auto bbox_num = id_list.size();
for (size_t i = 0; i < bbox_num; i++)
{
filter_res.push_back({ id_list[i],socre_list[i],box_list[i] });
}
std::stable_sort(filter_res.begin(), filter_res.end(),
[](const std::tuple<int, float, cv::Rect2f>& tuple1, const std::tuple<int, float, cv::Rect2f>& tuple2) {
return std::get<1>(tuple1) > std::get<1>(tuple2);
}
);
int idx = 0;
for (auto res : filter_res) {
bool keep = true;
for (int k = 0; k < nms_res.size() && keep; ++k) {
if (std::get<0>(res) == std::get<0>(nms_res[k])) {
if (1.f - jaccardDistance(std::get<2>(res), std::get<2>(nms_res[k])) > IOU) {
keep = false;
}
}
}
if (keep == true)
nms_res.emplace_back(res);
if (idx > max_nms) {
break;
}
idx++;
}
return nms_res;
};
std::vector<std::vector<float>> coordTrans(std::vector<std::tuple<int, float, cv::Rect2f>>& nms_res, PicPre& img, bool check_border = true) {
std::vector<std::vector<float>> output_data;
int left_pad = img.getPad().first;
int top_pad = img.getPad().second;
float ratio = img.getRatio().first;
//std::cout <<"ratio: " << ratio << std::endl;
for (auto&& res : nms_res) {
float class_id = std::get<0>(res);
float score = std::get<1>(res);
auto box = std::get<2>(res);
float x1 = (box.tl().x - left_pad) / ratio;
float y1 = (box.tl().y - top_pad) / ratio;
float x2 = (box.br().x - left_pad) / ratio;
float y2 = (box.br().y - top_pad) / ratio;
if (check_border) {
x1 = checkBorder(x1, 0.f, (float)img.src_img.cols);
y1 = checkBorder(y1, 0.f, (float)img.src_img.rows);
x2 = checkBorder(x2, 0.f, (float)img.src_img.cols);
y2 = checkBorder(y2, 0.f, (float)img.src_img.rows);
}
float w = x2 - x1;
float h = y2 - y1;
//bbox左上角点和wh
output_data.emplace_back(std::vector<float>({ class_id, x1, y1, w, h, score }));
}
return output_data;
}
void visualize(std::vector<std::vector<float>>& output_res, const cv::Mat& img, const std::string resRoot, const std::string name, const std::vector<std::string>& names) {
std::default_random_engine e;
std::uniform_int_distribution<unsigned> u(10, 200);
for (auto res : output_res) {
int class_id = (int)res[0];
float x1 = res[1];
float y1 = res[2];
float w = res[3];
float h = res[4];
float score = res[5];
cv::Scalar color_ = cv::Scalar(u(e), u(e), u(e));
cv::rectangle(img, cv::Rect(x1, y1, w, h), color_, 2);
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << score;
std::string s = std::to_string(class_id) + "_" + names[class_id] + " " + ss.str();
auto s_size = cv::getTextSize(s, cv::FONT_HERSHEY_DUPLEX, 0.5, 1, 0);
cv::rectangle(img, cv::Point(x1 - 1, y1 - s_size.height - 7), cv::Point(x1 + s_size.width, y1 - 2), color_, -1);
cv::putText(img, s, cv::Point(x1, y1 - 2), cv::FONT_HERSHEY_DUPLEX, 0.5, cv::Scalar(255, 255, 255), 0.2);
}
#ifdef _WIN32
cv::imshow("results", img);
cv::waitKey(0);
#elif __linux__
std::string save_path = resRoot + '/' + name;
std::regex rgx("\\.(?!.*\\.)"); // 匹配最后一个点号(.)之前的位置,且该点号后面没有其他点号
std::string RES_PATH = std::regex_replace(save_path, rgx, "_result.");
cv::imwrite(RES_PATH, img);
#endif
}
void saveRes(std::vector<std::vector<float>>& output_res, std::string resRoot, std::string name) {
std::string save_path = resRoot + '/' + name;
std::regex reg(R"(\.(\w*)$)");
save_path = std::regex_replace(save_path, reg, ".txt");
std::ofstream outputFile(save_path);
if (!outputFile.is_open()) {
std::cout << "Create txt file fail." << std::endl;
}
for (auto i : output_res) {
for (auto j : i) {
outputFile << j << " ";
}
outputFile << "\n";
}
outputFile.close();
}
/**
* @description: 在cvMat上绘制信息
* @param input_img 输入的cvMat
* @param text 右上角信息一般为fps数值
* @param model_name 左上角信息,一般为模型名称
* @param color 信息颜色
* @return {*}
* @notes:
*/
void drawText(cv::Mat& input_img, const std::string& text, const std::string& model_name, cv::Scalar color){
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;
int baseline;
auto text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Point origin;
origin.x = 0;
origin.y = 0;
// origin.x = input_img.cols / 2 - text_size.width / 2;
// origin.y = input_img.rows / 2 + text_size.height / 2;
//cv::rectangle(input_img, origin, cv::Point(origin.x + text_size.width + 10, origin.y + text_size.height + 10), (0, 0, 0), -1);
cv::putText(input_img, text, cv::Point(origin.x, origin.y + + text_size.height), font_face, font_scale, color, thickness);
cv::Point model_name_pos;
auto model_name_text_size = cv::getTextSize(model_name, font_face, font_scale, thickness, &baseline);
model_name_pos.x = input_img.cols - model_name_text_size.width;
model_name_pos.y = 0;
//cv::rectangle(input_img, model_name_pos, cv::Point(model_name_pos.x + model_name_text_size.width, model_name_pos.y + model_name_text_size.height + 10), (0, 0, 0), -1);
cv::putText(input_img, model_name, cv::Point(model_name_pos.x, model_name_pos.y + + model_name_text_size.height), font_face, font_scale, color, thickness);
}
void drawText(cv::Mat& input_img, const std::string& text, cv::Scalar color) {
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;
int baseline;
auto text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Point origin;
origin.x = 0;
origin.y = 0;
// origin.x = input_img.cols / 2 - text_size.width / 2;
// origin.y = input_img.rows / 2 + text_size.height / 2;
//cv::rectangle(input_img, origin, cv::Point(origin.x + text_size.width + 10, origin.y + text_size.height + 10), (0, 0, 0), -1);
cv::putText(input_img, text, cv::Point(origin.x, origin.y + +text_size.height), font_face, font_scale, color, thickness);
}
void drawTextTopLeft(cv::Mat& input_img, const std::string& text, cv::Scalar color) {
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 1;
int thickness = 1;
int baseline;
auto text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Point origin;
origin.x = 10;
origin.y = 10;
// origin.x = input_img.cols / 2 - text_size.width / 2;
// origin.y = input_img.rows / 2 + text_size.height / 2;
//cv::rectangle(input_img, origin, cv::Point(origin.x + text_size.width + 10, origin.y + text_size.height + 10), (0, 0, 0), -1);
cv::putText(input_img, text, cv::Point(origin.x, origin.y + +text_size.height), font_face, font_scale, color, thickness);
}
void drawTextFourConer(cv::Mat& input_img, const std::string& text, const std::string& fps, cv::Scalar color) {
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 1;
int thickness = 1;
int baseline;
auto text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Point origin;
origin.x = 10;
origin.y = 10;
cv::putText(input_img, fps, cv::Point(10, 10 + text_size.height), font_face, font_scale, color, thickness);
cv::putText(input_img, text, cv::Point(input_img.cols - 10 - text_size.width, 10 + text_size.height), font_face, font_scale, color, thickness);
cv::putText(input_img, text, cv::Point(10, input_img.rows - 10 - text_size.height), font_face, font_scale, color, thickness);
cv::putText(input_img, text, cv::Point(input_img.cols - 10 - text_size.width, input_img.rows - 10 - text_size.height), font_face, font_scale, color, thickness);
}
void drawTextTwoConer(cv::Mat& input_img, const std::string& text, const std::string& fps, cv::Scalar color) {
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 1;
int thickness = 1;
int baseline;
auto text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
cv::Point origin;
origin.x = 10;
origin.y = 10;
cv::putText(input_img, fps, cv::Point(10, 10 + text_size.height), font_face, font_scale, color, thickness);
cv::putText(input_img, text, cv::Point(input_img.cols - 10 - text_size.width, 10 + text_size.height), font_face, font_scale, color, thickness);
}
const int kColorMap[][3] = { {255, 128, 0}, {255, 153, 51}, {255, 178, 102}, {230, 230, 0}, {255, 153, 255},
{153, 204, 255}, {255, 102, 255}, {255, 51, 255}, {102, 178, 255}, {51, 153, 255},
{255, 153, 153}, {255, 102, 102}, {255, 51, 51}, {153, 255, 153}, {102, 255, 102},
{51, 255, 51}, {0, 255, 0}, {0, 0, 255}, {255, 0, 0}, {128, 255, 255} };
std::default_random_engine e;
std::uniform_int_distribution<unsigned> u(0, 255);
cv::Scalar randomColor() {
return cv::Scalar(u(e), u(e), u(e));
}
cv::Scalar classColor(int id) {
return cv::Scalar(kColorMap[id%20][0], kColorMap[id%20][1], kColorMap[id%20][2]);
}
void FlipPer4(int16_t* tensor_data, int size) {
for (int i = 0; i < size; i += 4) {
int16_t a0 = tensor_data[i + 0];
int16_t a1 = tensor_data[i + 1];
int16_t a2 = tensor_data[i + 2];
int16_t a3 = tensor_data[i + 3];
tensor_data[i + 3] = a0;
tensor_data[i + 2] = a1;
tensor_data[i + 1] = a2;
tensor_data[i + 0] = a3;
}
}
/**
* @description: 正确版本的nms
* @param box_list 推理出来的的bbox列表
* @param socre_list 置信度列表
* @param conf 筛选置信度阈值
* @param iou 筛选的iou阈值
* @return {*}
* @notes:
*/
std::vector<int> nms(std::vector<cv::Rect>& box_list, std::vector<float>& socre_list, std::vector<int>& id_list, const float& conf, const float& iou, const int& NOC) {
std::vector<int> nms_indices;
for (int class_id = 0; class_id < NOC; class_id++) {
std::vector<std::pair<float, int> > score_index_vec;
for (size_t i = 0; i < socre_list.size(); ++i) {
if (socre_list[i] > conf && id_list[i] == class_id) {
score_index_vec.emplace_back(std::make_pair(socre_list[i], i));
}
}
std::stable_sort(score_index_vec.begin(), score_index_vec.end(),
[](const std::pair<float, int>& pair1, const std::pair<float, int>& pair2) {return pair1.first > pair2.first; });
for (size_t i = 0; i < score_index_vec.size(); ++i) {
const int idx = score_index_vec[i].second;
bool keep = true;
for (int k = 0; k < nms_indices.size() && keep; ++k) {
if (1.f - jaccardDistance(box_list[idx], box_list[nms_indices[k]]) > iou) {
keep = false;
}
}
if (keep == true)
nms_indices.emplace_back(idx);
}
}
return nms_indices;
}