In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "how to realize yolov5 to onnx in C++". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Training model. PT to onnx
The training part decides whether or not to write a blog according to the voice.
Note:
1. The training code must choose yolov5 version 5. 0
two。 Enter models/exprort.py
3. Replace the red box area with your own training model.
4. Change the version to 12
5. Just run it directly, and a model of onnx will be generated.
Analysis of C++ Code
The blogger uses the opencv4.5.3 version, which has been compiled. You need to scan the code directly and I will send you.
Main function part
Read the model using dnn::readNet,opencv is actually quite powerful bloggers have read the tf model, torch model will be followed by the corresponding blog, here a total of three changes, enter the picture path, enter the category name class_names,net part to change to their own model
Net.set these parameters are fixed, interested students can study DNN_TARGET_CPU this place, you can use gpu and cuda, but the blogger has not reproduced
The reasoning part explains void postprocess (cv::Mat& cv_src, std::vector& outs, const std::vector& classes, int net_size) {float confThreshold = 0.1f; float nmsThreshold = 0.1f; std::vector classIds; std::vector confidences; std::vector boxes; int strides [] = {8,16,32} Std::vector anchors = {{10pr 13,16rect 30,3je 23}, {30pr 61,62pr 45, 59119}, {116pr 90,156jre 198,373326}}; for (size_t k = 0; k)
< outs.size(); k++) { float* data = outs[k].ptr(); int stride = strides[k]; int num_classes = outs[k].size[4] - 5; for (int i = 0; i < outs[k].size[2]; i++) { for (int j = 0; j < outs[k].size[3]; j++) { for (int a = 0; a < outs[k].size[1]; ++a) { float* record = data + a * outs[k].size[2] * outs[k].size[3] * outs[k].size[4] + i * outs[k].size[3] * outs[k].size[4] + j * outs[k].size[4]; float* cls_ptr = record + 5; for (int cls = 0; cls < num_classes; cls++) { float score = sigmoid(cls_ptr[cls]) * sigmoid(record[4]); if (score >ConfThreshold) {float cx = (sigmoid (record [0]) * 2.f-0.5f + (float) j) * (float) stride Float cy = (sigmoid (record [1]) * 2.f-0.5f + (float) I) * (float) stride; float w = pow (sigmoid (record [2]) * 2.f, 2) * anchors [k] [2 * a] Float h = pow (sigmoid (record [3]) * 2.f, 2) * anchors [k] [2 * a + 1] Float x1 = std::max (0, std::min (cv_src.cols, int ((cx-w / 2.f) * (float) cv_src.cols / (float) net_size) Float Y1 = std::max (0, std::min (cv_src.rows, int ((cy-h / 2.f) * (float) cv_src.rows / (float) net_size) Float x2 = std::max (0, std::min (cv_src.cols, int ((cx + w / 2.f) * (float) cv_src.cols / (float) net_size) Float y2 = std::max (0, std::min (cv_src.rows, int ((cy + h / 2.f) * (float) cv_src.rows / (float) net_size)); classIds.push_back (cls) Confidences.push_back (score); boxes.push_back (cv::Rect (cv::Point (x1, y1), cv::Point (x2, y2) }} std::vector indices; cv::dnn::NMSBoxes (boxes, confidences, confThreshold, nmsThreshold, indices) For (size_t I = 0; I < indices.size (); iTunes +) {int idx = indices [I]; cv::Rect box = boxes [idx]; drawPred (classIds [idx], confidences [idx], box.x, box.y, box.x + box.width, box.y + box.height, cv_src, classes);}}
The head-up part is the threshold setting for the two major targets detection, and then anchors is not recommended to move. Unless you use the anchors generated by yourself during training, change it to your own. Then after reasoning according to the training, you will generate our corresponding coordinate box and score, and send the score and madness to the container. There are underlying functions such as nms in dnn.
Cv::dnn::NMSBoxes (boxes, confidences, confThreshold, nmsThreshold, indices)
Just correspond to the input, and then get our Box,index and confidence, and then it's time for our drawing.
Darpred partial void drawPred (int classId, float conf, int left, int top, int right, int bottom, cv::Mat& frame, const std::vector& classes) {cv::rectangle (frame, cv::Point (left, top), cv::Point (right, bottom), cv::Scalar (0,255,0), 3); std::string label = cv::format ("% .2f", conf) If (! classes.empty ()) {CV_Assert (classId < (int) classes.size ()); label = classes [classId] + ":" + label;} int baseLine; cv::Size labelSize = cv::getTextSize (label, cv::FONT_HERSHEY_SIMPLEX, 0.5,1, & baseLine); top = std::max (top, labelSize.height) Cv::rectangle (frame, cv::Point (left, top-round), cv::Point (left + round (1.5 * labelSize.width), top + baseLine), cv::Scalar (0,255,0), cv::FILLED); cv::putText (frame, label, cv::Point (left, top), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar (), 2) } sigmod part inline float sigmoid (float x) {return 1.f / (1.f + exp (- x));} "how to convert C++ from yolov5 to onnx" ends here. Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.