当前位置:网站首页>Raspberry pie 4B uses MNN to deploy yolov5 Lite
Raspberry pie 4B uses MNN to deploy yolov5 Lite
2022-07-28 20:31:00 【Effort & struggle】
List of articles
One 、 Raspberry pie configuration MNN
download MNN And compile
git clone https://gitee.com/mirrors/mnn.git
cd MNN
mkdir build
cmake ..
make -j4After completion MNN The folder is as follows

Two 、 Deploy Yolov5-lite Model
1. take pt The model is converted to onnx Model , And convert
Refer to the last blog Raspberry pie 4B Use NCNN Deploy Yolov5-lite_ Strive && Struggling blog -CSDN Blog
2. take onnx The model is converted to mnn Model
cd MNN/build
./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel XXX.mnn --bizCode biz3. transplant yolov5lite official mnn_demo
take cpp_demo/mnn Transplant it into raspberry pie
4. modify main.cpp
Follow ncnn similar ,mnn It also needs to be modified in anchors related data

The first column is the output layer name, The second as stride, The rest follow v5lite-e.yaml in anchors bring into correspondence with
How to determine the names
utilize MNN The tools that come with you will mnn The model is converted to json
cd MNN/build
./MNNDump2Json xxx.mnn xxx.json
open json File found the last three permute, They correspond to each other stride8 16 32 Of name



5. Compile and execute
cd mnn
mkdir build
cd build
cmake ..
make
../yolov5bug1:
Error: can't find output: 451
Error: can't find output: 479
Error: can't find output: 507
this bug Because it is not used saveTensors Save output node , Need to be in MNN::Session *session = net->createSession(config); with saveTensors. The specific changes are as follows
int main()
{
std::string model_name = "weights/e.mnn";
int num_classes=2;
std::vector<YoloLayerData> yolov5s_layers{
{"507", 32, {
{116, 90}, {156, 198}, {373, 326}}},
{"479", 16, {
{30, 61}, {62, 45}, {59, 119}}},
{"451", 8, {
{10, 13}, {16, 30}, {33, 23}}},
};
std::vector<YoloLayerData> & layers = yolov5s_layers;
int net_size =640;
// get output data
std::string output_tensor_name0 = layers[2].name ;
std::string output_tensor_name1 = layers[1].name ;
std::string output_tensor_name2 = layers[0].name ;
std::shared_ptr<MNN::Interpreter> net = std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile(model_name.c_str()));
if (nullptr == net) {
return 0;
}
MNN::ScheduleConfig config;
config.numThread = 4;
config.type = static_cast<MNNForwardType>(MNN_FORWARD_CPU);
MNN::BackendConfig backendConfig;
backendConfig.precision = (MNN::BackendConfig::PrecisionMode)2;
// backendConfig.precision = MNN::PrecisionMode Precision_Normal; // static_cast<PrecisionMode>(Precision_Normal);
config.backendConfig = &backendConfig;
std::vector<std::string> saveNamesVector;
saveNamesVector.push_back(output_tensor_name0);
saveNamesVector.push_back(output_tensor_name1);
saveNamesVector.push_back(output_tensor_name2);
config.saveTensors = saveNamesVector;
MNN::Session *session = net->createSession(config);
cv::VideoCapture capture;
capture.open(0); // Modify this parameter to select the camera you want to use
cv::Mat frame;
while(1)
{
int INPUT_SIZE = 320;
/*std::string image_name = "1.jpg";
// load image
cv::Mat raw_image = cv::imread(image_name.c_str());
cv::Mat image;
*/
capture >> frame;
cv::Mat image;
cv::flip(frame, image, 1);
cv::Mat raw_image = image;
cv::resize(raw_image, image, cv::Size(INPUT_SIZE, INPUT_SIZE));
// preprocessing
image.convertTo(image, CV_32FC3);
// image = (image * 2 / 255.0f) - 1;
image = image /255.0f;
// wrapping input tensor, convert nhwc to nchw
std::vector<int> dims{1, INPUT_SIZE, INPUT_SIZE, 3};
auto nhwc_Tensor = MNN::Tensor::create<float>(dims, NULL, MNN::Tensor::TENSORFLOW);
auto nhwc_data = nhwc_Tensor->host<float>();
auto nhwc_size = nhwc_Tensor->size();
std::memcpy(nhwc_data, image.data, nhwc_size);
auto inputTensor = net->getSessionInput(session, nullptr);
inputTensor->copyFromHostTensor(nhwc_Tensor);
// run network
clock_t startTime,endTime;
startTime = clock();// Timing begins
net->runSession(session);
endTime = clock();// End of the timing
cout << "The forward time is: " <<(double)(endTime - startTime) / 1000.0 << "ms" << endl;
MNN::Tensor *tensor_scores = net->getSessionOutput(session, output_tensor_name0.c_str());
MNN::Tensor *tensor_boxes = net->getSessionOutput(session, output_tensor_name1.c_str());
MNN::Tensor *tensor_anchors = net->getSessionOutput(session, output_tensor_name2.c_str());
MNN::Tensor tensor_scores_host(tensor_scores, tensor_scores->getDimensionType());
MNN::Tensor tensor_boxes_host(tensor_boxes, tensor_boxes->getDimensionType());
MNN::Tensor tensor_anchors_host(tensor_anchors, tensor_anchors->getDimensionType());
tensor_scores->copyToHostTensor(&tensor_scores_host);
tensor_boxes->copyToHostTensor(&tensor_boxes_host);
tensor_anchors->copyToHostTensor(&tensor_anchors_host);
std::vector<BoxInfo> result;
std::vector<BoxInfo> boxes;
yolocv::YoloSize yolosize = yolocv::YoloSize{INPUT_SIZE,INPUT_SIZE};
float threshold = 0.25;
float nms_threshold = 0.5;
// show_shape(tensor_scores_host.shape());
// show_shape(tensor_boxes_host.shape());
// show_shape(tensor_anchors_host.shape());
boxes = decode_infer(tensor_scores_host, layers[2].stride, yolosize, net_size, num_classes, layers[2].anchors, threshold);
result.insert(result.begin(), boxes.begin(), boxes.end());
boxes = decode_infer(tensor_boxes_host, layers[1].stride, yolosize, net_size, num_classes, layers[1].anchors, threshold);
result.insert(result.begin(), boxes.begin(), boxes.end());
boxes = decode_infer(tensor_anchors_host, layers[0].stride, yolosize, net_size, num_classes, layers[0].anchors, threshold);
result.insert(result.begin(), boxes.begin(), boxes.end());
nms(result, nms_threshold);
// std::cout<<result.size()<<std::endl;
scale_coords(result, INPUT_SIZE, INPUT_SIZE, raw_image.cols, raw_image.rows);
cv::Mat frame_show = draw_box(raw_image, result);
//cv::imwrite("output.jpg", frame_show);
cv::imshow("outpt", frame_show);
if (cv::waitKey(30) >= 0)
break;
}
return 0;
}bug2: Segmentation fault
Inputsize by 640,onnx During model conversion size by 320, Be consistent , So it's changed to 320.
6. Final effect

summary
MNN Compared with NCNN More operators are supported , And the reasoning speed is also faster
边栏推荐
- Solve the problem that jupyter cannot import new packages
- Solve the kangaroo crossing problem (DP)
- Linux Installation MySQL (pit filling version)
- [POC - proof of concept]
- Shanghai Jiaotong University joined hands with Taobao to set up a media computing laboratory: promoting the development of key technologies such as video super score
- Read JSON configuration file to realize data-driven testing
- One article makes you understand what typescript is
- 字符设备驱动结构
- [dynamic link library (DLL) initialization example program failed "problem]
- C language data 3 (1)
猜你喜欢

C language - data storage

Quick sort template

Solutions to the environment created by Anaconda that cannot be displayed in pycharm

Store and guarantee rancher data based on Minio objects

Usage Summary of thymeleaf

9. Pointer of C language (5) how many bytes does the pointer variable occupy

Anaconda creation environment

How to automatically store email attachments in SharePoint

Item exception handling in SSM

【CodeForces】Educational Codeforces Round 132 (Rated for Div. 2)
随机推荐
Solve the kangaroo crossing problem (DP)
Related concepts of multitasking programming
Common commands of raspberry pie
上海交大牵手淘宝成立媒体计算实验室:推动视频超分等关键技术发展
Linxu 【基本指令】
Method number problem for solving sum of numbers (knapsack problem)
Residual network RESNET source code analysis - pytoch version
Raspberry pie creation self start service
Linxu 【权限,粘滞位】
7. Functions of C language, function definitions and the order of function calls, how to declare functions, prime examples, formal parameters and arguments, and how to write a function well
通配符 SSL/TLS 证书
Using typedef in C language to change the name of data type
3、 Are formal and actual parameters in a programming language variables?
WPF--实现WebSocket服务端
WPF -- implement websocket server
C language data 3 (2)
Introduction to seven kinds of polling (practice link attached)
Torch. NN. Linear() function
Networkx common operations summary (for personal use)
Pytorch model parameter assignment - tensor.copy_ () method