9.7 visual studio 搭建yolov10的onnx的猜测(c++)

打印 上一主题 下一主题

主题 1024|帖子 1024|积分 3072

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1.环境设置

在进行onnx猜测前,须要搭建的环境如下:
1.opencv环境的设置,可参考博客:9.2 c++搭建opencv环境-CSDN博客
2.libtorch环境的设置,可参考博客:9.4 visualStudio 2022 设置 cuda 和 torch (c++)-CSDN博客
3.cuda环境的设置,可参考博客:9.4 visualStudio 2022 设置 cuda 和 torch (c++)-CSDN博客
4.onnx环境的设置,可参考博客:VS2019设置ONNXRuntime c++环境_microsoft.ml.onnxruntime-CSDN博客
2.yolov10的c++代码

该代码做了部分的修改,末了调试成功。具体的代码如下:
main.cpp
  1. #include <iostream>
  2. //#include <getopt.h>
  3. #include "yolov5v8_dnn.h"
  4. #include "yolov5v8_ort.h"
  5. using namespace std;
  6. using namespace cv;
  7. void main(int argc, char** argv)
  8. {
  9.     string img_path = "E:\\vs\\daima\\1_8\\Project1\\x64\\Release\\street.jpg";
  10.     string model_path = "E:\\vs\\daima\\1_8\\Project1\\x64\\Release\\yolov8n-seg.onnx";
  11.     string test_cls = "dnn";
  12.     if (test_cls == "dnn") {
  13.         // Input the path of model ("yolov8s.onnx" or "yolov5s.onnx") to run Inference with yolov8/yolov5 (ONNX)
  14.         // Note that in this example the classes are hard-coded and 'classes.txt' is a place holder.
  15.         Inference inf(model_path, cv::Size(640, 640), "classes.txt", true);
  16.         cv::Mat frame = cv::imread(img_path);
  17.         std::vector<Detection> output = inf.runInference(frame);
  18.         if (output.size() != 0) inf.DrawPred(frame, output);
  19.         else cout << "Detect Nothing!" << endl;
  20.     }
  21.     if (test_cls == "ort") {
  22.         DCSP_CORE* yoloDetector = new DCSP_CORE;
  23. #ifdef USE_CUDA
  24.         //DCSP_INIT_PARAM params{ model_path, YOLO_ORIGIN_V5, {640, 640},  0.25, 0.45, 0.5, true }; // GPU FP32 inference
  25.         DCSP_INIT_PARAM params{ model_path, YOLO_ORIGIN_V5_HALF, {640, 640},  0.25, 0.45, 0.5, true }; // GPU FP16 inference
  26. #else
  27.         DCSP_INIT_PARAM params{ model_path, YOLO_ORIGIN_V5, {640, 640},0.25, 0.45, 0.5, false };  // CPU inference
  28. #endif
  29.         yoloDetector->CreateSession(params);
  30.         cv::Mat img = cv::imread(img_path);
  31.         std::vector<DCSP_RESULT> res;
  32.         yoloDetector->RunSession(img, res);
  33.         if (res.size() != 0) yoloDetector->DrawPred(img, res);
  34.         else cout << "Detect Nothing!" << endl;
  35.     }
  36. }
复制代码
yolov5v8_dnn.cpp
  1. #include "yolov5v8_dnn.h"
  2. using namespace std;
  3. Inference::Inference(const std::string& onnxModelPath, const cv::Size& modelInputShape, const std::string& classesTxtFile, const bool& runWithCuda)
  4. {
  5.     modelPath = onnxModelPath;
  6.     modelShape = modelInputShape;
  7.     classesPath = classesTxtFile;
  8.     cudaEnabled = runWithCuda;
  9.     loadOnnxNetwork();
  10.     // loadClassesFromFile(); The classes are hard-coded for this example
  11. }
  12. std::vector<Detection> Inference::runInference(const cv::Mat& input)
  13. {
  14.     cv::Mat SrcImg = input;
  15.     cv::Mat netInputImg;
  16.     cv::Vec4d params;
  17.     LetterBox(SrcImg, netInputImg, params, cv::Size(modelShape.width, modelShape.height));
  18.     cv::Mat blob;
  19.     cv::dnn::blobFromImage(netInputImg, blob, 1.0 / 255.0, modelShape, cv::Scalar(), true, false);
  20.     net.setInput(blob);
  21.     std::vector<cv::Mat> outputs;
  22.     net.forward(outputs, net.getUnconnectedOutLayersNames());
  23.     if (outputs.size() == 2) RunSegmentation = true;
  24.     int rows = outputs[0].size[1];
  25.     int dimensions = outputs[0].size[2];
  26.     bool yolov8 = false;
  27.     // yolov5 has an output of shape (batchSize, 25200, 85) (Num classes + box[x,y,w,h] + confidence[c])
  28.     // yolov8 has an output of shape (batchSize, 84,  8400) (Num classes + box[x,y,w,h])
  29.     if (dimensions > rows) // Check if the shape[2] is more than shape[1] (yolov8)
  30.     {
  31.         yolov8 = true;
  32.         rows = outputs[0].size[2];
  33.         dimensions = outputs[0].size[1];
  34.         outputs[0] = outputs[0].reshape(1, dimensions);
  35.         cv::transpose(outputs[0], outputs[0]);
  36.     }
  37.     float* data = (float*)outputs[0].data;
  38.     std::vector<int> class_ids;
  39.     std::vector<float> confidences;
  40.     std::vector<cv::Rect> boxes;
  41.     std::vector<vector<float>> picked_proposals;
  42.     for (int i = 0; i < rows; ++i)
  43.     {
  44.         int _segChannels;
  45.         if (yolov8)
  46.         {
  47.             float* classes_scores = data + 4;
  48.             cv::Mat scores(1, classes.size(), CV_32FC1, classes_scores);
  49.             cv::Point class_id;
  50.             double maxClassScore;
  51.             minMaxLoc(scores, 0, &maxClassScore, 0, &class_id);
  52.             if (maxClassScore > modelScoreThreshold)
  53.             {
  54.                 if (RunSegmentation) {
  55.                     _segChannels = outputs[1].size[1];
  56.                     vector<float> temp_proto(data + classes.size() + 4, data + classes.size() + 4 + _segChannels);
  57.                     picked_proposals.push_back(temp_proto);
  58.                 }
  59.                 confidences.push_back(maxClassScore);
  60.                 class_ids.push_back(class_id.x);
  61.                 float x = (data[0] - params[2]) / params[0];
  62.                 float y = (data[1] - params[3]) / params[1];
  63.                 float w = data[2] / params[0];
  64.                 float h = data[3] / params[1];
  65.                 int left = MAX(round(x - 0.5 * w + 0.5), 0);
  66.                 int top = MAX(round(y - 0.5 * h + 0.5), 0);
  67.                 if ((left + w) > SrcImg.cols) { w = SrcImg.cols - left; }
  68.                 if ((top + h) > SrcImg.rows) { h = SrcImg.rows - top; }
  69.                 boxes.push_back(cv::Rect(left, top, int(w), int(h)));
  70.             }
  71.         }
  72.         else // yolov5
  73.         {
  74.             float confidence = data[4];
  75.             if (confidence >= modelConfidenceThreshold)
  76.             {
  77.                 float* classes_scores = data + 5;
  78.                 cv::Mat scores(1, classes.size(), CV_32FC1, classes_scores);
  79.                 cv::Point class_id;
  80.                 double max_class_score;
  81.                 minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
  82.                 if (max_class_score > modelScoreThreshold)
  83.                 {
  84.                     if (RunSegmentation) {
  85.                         _segChannels = outputs[1].size[1];
  86.                         vector<float> temp_proto(data + classes.size() + 5, data + classes.size() + 5 + _segChannels);
  87.                         picked_proposals.push_back(temp_proto);
  88.                     }
  89.                     confidences.push_back(confidence);
  90.                     class_ids.push_back(class_id.x);
  91.                     float x = (data[0] - params[2]) / params[0];
  92.                     float y = (data[1] - params[3]) / params[1];
  93.                     float w = data[2] / params[0];
  94.                     float h = data[3] / params[1];
  95.                     int left = MAX(round(x - 0.5 * w + 0.5), 0);
  96.                     int top = MAX(round(y - 0.5 * h + 0.5), 0);
  97.                     if ((left + w) > SrcImg.cols) { w = SrcImg.cols - left; }
  98.                     if ((top + h) > SrcImg.rows) { h = SrcImg.rows - top; }
  99.                     boxes.push_back(cv::Rect(left, top, int(w), int(h)));
  100.                 }
  101.             }
  102.         }
  103.         data += dimensions;
  104.     }
  105.     std::vector<int> nms_result;
  106.     cv::dnn::NMSBoxes(boxes, confidences, modelScoreThreshold, modelNMSThreshold, nms_result);
  107.     std::vector<Detection> detections{};
  108.     std::vector<vector<float>> temp_mask_proposals;
  109.     for (unsigned long i = 0; i < nms_result.size(); ++i)
  110.     {
  111.         int idx = nms_result[i];
  112.         Detection result;
  113.         result.class_id = class_ids[idx];
  114.         result.confidence = confidences[idx];
  115.         std::random_device rd;
  116.         std::mt19937 gen(rd());
  117.         std::uniform_int_distribution<int> dis(100, 255);
  118.         result.color = cv::Scalar(dis(gen),
  119.             dis(gen),
  120.             dis(gen));
  121.         result.className = classes[result.class_id];
  122.         result.box = boxes[idx];
  123.         if (RunSegmentation) temp_mask_proposals.push_back(picked_proposals[idx]);
  124.         if (result.box.width != 0 && result.box.height != 0) detections.push_back(result);
  125.     }
  126.     if (RunSegmentation) {
  127.         cv::Mat mask_proposals;
  128.         for (int i = 0; i < temp_mask_proposals.size(); ++i)
  129.             mask_proposals.push_back(cv::Mat(temp_mask_proposals[i]).t());
  130.         GetMask(mask_proposals, outputs[1], params, SrcImg.size(), detections);
  131.     }
  132.     return detections;
  133. }
  134. void Inference::loadClassesFromFile()
  135. {
  136.     std::ifstream inputFile(classesPath);
  137.     if (inputFile.is_open())
  138.     {
  139.         std::string classLine;
  140.         while (std::getline(inputFile, classLine))
  141.             classes.push_back(classLine);
  142.         inputFile.close();
  143.     }
  144. }
  145. void Inference::loadOnnxNetwork()
  146. {
  147.     net = cv::dnn::readNetFromONNX(modelPath);
  148.     if (cudaEnabled)
  149.     {
  150.         std::cout << "\nRunning on CUDA" << std::endl;
  151.         net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
  152.         net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
  153.     }
  154.     else
  155.     {
  156.         std::cout << "\nRunning on CPU" << std::endl;
  157.         net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
  158.         net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
  159.     }
  160. }
  161. void Inference::LetterBox(const cv::Mat& image, cv::Mat& outImage, cv::Vec4d& params, const cv::Size& newShape,
  162.     bool autoShape, bool scaleFill, bool scaleUp, int stride, const cv::Scalar& color)
  163. {
  164.     if (false) {
  165.         int maxLen = MAX(image.rows, image.cols);
  166.         outImage = cv::Mat::zeros(cv::Size(maxLen, maxLen), CV_8UC3);
  167.         image.copyTo(outImage(cv::Rect(0, 0, image.cols, image.rows)));
  168.         params[0] = 1;
  169.         params[1] = 1;
  170.         params[3] = 0;
  171.         params[2] = 0;
  172.     }
  173.     cv::Size shape = image.size();
  174.     float r = std::min((float)newShape.height / (float)shape.height,
  175.         (float)newShape.width / (float)shape.width);
  176.     if (!scaleUp)
  177.         r = std::min(r, 1.0f);
  178.     float ratio[2]{ r, r };
  179.     int new_un_pad[2] = { (int)std::round((float)shape.width * r),(int)std::round((float)shape.height * r) };
  180.     auto dw = (float)(newShape.width - new_un_pad[0]);
  181.     auto dh = (float)(newShape.height - new_un_pad[1]);
  182.     if (autoShape)
  183.     {
  184.         dw = (float)((int)dw % stride);
  185.         dh = (float)((int)dh % stride);
  186.     }
  187.     else if (scaleFill)
  188.     {
  189.         dw = 0.0f;
  190.         dh = 0.0f;
  191.         new_un_pad[0] = newShape.width;
  192.         new_un_pad[1] = newShape.height;
  193.         ratio[0] = (float)newShape.width / (float)shape.width;
  194.         ratio[1] = (float)newShape.height / (float)shape.height;
  195.     }
  196.     dw /= 2.0f;
  197.     dh /= 2.0f;
  198.     if (shape.width != new_un_pad[0] && shape.height != new_un_pad[1])
  199.     {
  200.         cv::resize(image, outImage, cv::Size(new_un_pad[0], new_un_pad[1]));
  201.     }
  202.     else {
  203.         outImage = image.clone();
  204.     }
  205.     int top = int(std::round(dh - 0.1f));
  206.     int bottom = int(std::round(dh + 0.1f));
  207.     int left = int(std::round(dw - 0.1f));
  208.     int right = int(std::round(dw + 0.1f));
  209.     params[0] = ratio[0];
  210.     params[1] = ratio[1];
  211.     params[2] = left;
  212.     params[3] = top;
  213.     cv::copyMakeBorder(outImage, outImage, top, bottom, left, right, cv::BORDER_CONSTANT, color);
  214. }
  215. void Inference::GetMask(const cv::Mat& maskProposals, const cv::Mat& mask_protos, const cv::Vec4d& params, const cv::Size& srcImgShape, std::vector<Detection>& output) {
  216.     if (output.size() == 0) return;
  217.     int _segChannels = mask_protos.size[1];
  218.     int _segHeight = mask_protos.size[2];
  219.     int _segWidth = mask_protos.size[3];
  220.     cv::Mat protos = mask_protos.reshape(0, { _segChannels,_segWidth * _segHeight });
  221.     cv::Mat matmulRes = (maskProposals * protos).t();
  222.     cv::Mat masks = matmulRes.reshape(output.size(), { _segHeight,_segWidth });
  223.     vector<cv::Mat> maskChannels;
  224.     split(masks, maskChannels);
  225.     for (int i = 0; i < output.size(); ++i) {
  226.         cv::Mat dest, mask;
  227.         //sigmoid
  228.         cv::exp(-maskChannels[i], dest);
  229.         dest = 1.0 / (1.0 + dest);
  230.         cv::Rect roi(int(params[2] / modelShape.width * _segWidth), int(params[3] / modelShape.height * _segHeight), int(_segWidth - params[2] / 2), int(_segHeight - params[3] / 2));
  231.         dest = dest(roi);
  232.         cv::resize(dest, mask, srcImgShape, cv::INTER_NEAREST);
  233.         //crop
  234.         cv::Rect temp_rect = output[i].box;
  235.         mask = mask(temp_rect) > modelScoreThreshold;
  236.         output[i].boxMask = mask;
  237.     }
  238. }
  239. void Inference::DrawPred(cv::Mat& img, vector<Detection>& result) {
  240.     int detections = result.size();
  241.     std::cout << "Number of detections:" << detections << std::endl;
  242.     cv::Mat mask = img.clone();
  243.     for (int i = 0; i < detections; ++i)
  244.     {
  245.         Detection detection = result[i];
  246.         cv::Rect box = detection.box;
  247.         cv::Scalar color = detection.color;
  248.         // Detection box
  249.         cv::rectangle(img, box, color, 2);
  250.         mask(detection.box).setTo(color, detection.boxMask);
  251.         // Detection box text
  252.         std::string classString = detection.className + ' ' + std::to_string(detection.confidence).substr(0, 4);
  253.         cv::Size textSize = cv::getTextSize(classString, cv::FONT_HERSHEY_DUPLEX, 1, 2, 0);
  254.         cv::Rect textBox(box.x, box.y - 40, textSize.width + 10, textSize.height + 20);
  255.         cv::rectangle(img, textBox, color, cv::FILLED);
  256.         cv::putText(img, classString, cv::Point(box.x + 5, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 0), 2, 0);
  257.     }
  258.     // Detection mask
  259.     if (RunSegmentation) cv::addWeighted(img, 0.5, mask, 0.5, 0, img); //将mask加在原图上面
  260.     cv::imshow("Inference", img);
  261.     cv::imwrite("out.bmp", img);
  262.     cv::waitKey();
  263.     cv::destroyWindow("Inference");
  264. }
复制代码
yolov5v8_ort.cpp
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "yolov5v8_ort.h"
  3. #include <regex>
  4. #include <random>
  5. #define benchmark
  6. using namespace std;
  7. DCSP_CORE::DCSP_CORE() {
  8. }
  9. DCSP_CORE::~DCSP_CORE() {
  10.     delete session;
  11. }
  12. #ifdef USE_CUDA
  13. namespace Ort
  14. {
  15.     template<>
  16.     struct TypeToTensorType<half> { static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16; };
  17. }
  18. #endif
  19. template<typename T>
  20. char* BlobFromImage(cv::Mat& iImg, T& iBlob) {
  21.     int channels = iImg.channels();
  22.     int imgHeight = iImg.rows;
  23.     int imgWidth = iImg.cols;
  24.     for (int c = 0; c < channels; c++) {
  25.         for (int h = 0; h < imgHeight; h++) {
  26.             for (int w = 0; w < imgWidth; w++) {
  27.                 iBlob[c * imgWidth * imgHeight + h * imgWidth + w] = typename std::remove_pointer<T>::type(
  28.                     (iImg.at<cv::Vec3b>(h, w)[c]) / 255.0f);
  29.             }
  30.         }
  31.     }
  32.     return RET_OK;
  33. }
  34. char* PreProcess(cv::Mat& iImg, std::vector<int> iImgSize, cv::Mat& oImg) {
  35.     cv::Mat img = iImg.clone();
  36.     cv::resize(iImg, oImg, cv::Size(iImgSize.at(0), iImgSize.at(1)));
  37.     if (img.channels() == 1) {
  38.         cv::cvtColor(oImg, oImg, cv::COLOR_GRAY2BGR);
  39.     }
  40.     cv::cvtColor(oImg, oImg, cv::COLOR_BGR2RGB);
  41.     return RET_OK;
  42. }
  43. void LetterBox(const cv::Mat& image, cv::Mat& outImage, cv::Vec4d& params, const cv::Size& newShape = cv::Size(640, 640),
  44.     bool autoShape = false, bool scaleFill = false, bool scaleUp = true, int stride = 32, const cv::Scalar& color = cv::Scalar(114, 114, 114))
  45. {
  46.     if (false) {
  47.         int maxLen = MAX(image.rows, image.cols);
  48.         outImage = cv::Mat::zeros(cv::Size(maxLen, maxLen), CV_8UC3);
  49.         image.copyTo(outImage(cv::Rect(0, 0, image.cols, image.rows)));
  50.         params[0] = 1;
  51.         params[1] = 1;
  52.         params[3] = 0;
  53.         params[2] = 0;
  54.     }
  55.     cv::Size shape = image.size();
  56.     float r = std::min((float)newShape.height / (float)shape.height,
  57.         (float)newShape.width / (float)shape.width);
  58.     if (!scaleUp)
  59.         r = std::min(r, 1.0f);
  60.     float ratio[2]{ r, r };
  61.     int new_un_pad[2] = { (int)std::round((float)shape.width * r),(int)std::round((float)shape.height * r) };
  62.     auto dw = (float)(newShape.width - new_un_pad[0]);
  63.     auto dh = (float)(newShape.height - new_un_pad[1]);
  64.     if (autoShape)
  65.     {
  66.         dw = (float)((int)dw % stride);
  67.         dh = (float)((int)dh % stride);
  68.     }
  69.     else if (scaleFill)
  70.     {
  71.         dw = 0.0f;
  72.         dh = 0.0f;
  73.         new_un_pad[0] = newShape.width;
  74.         new_un_pad[1] = newShape.height;
  75.         ratio[0] = (float)newShape.width / (float)shape.width;
  76.         ratio[1] = (float)newShape.height / (float)shape.height;
  77.     }
  78.     dw /= 2.0f;
  79.     dh /= 2.0f;
  80.     if (shape.width != new_un_pad[0] && shape.height != new_un_pad[1])
  81.     {
  82.         cv::resize(image, outImage, cv::Size(new_un_pad[0], new_un_pad[1]));
  83.     }
  84.     else {
  85.         outImage = image.clone();
  86.     }
  87.     int top = int(std::round(dh - 0.1f));
  88.     int bottom = int(std::round(dh + 0.1f));
  89.     int left = int(std::round(dw - 0.1f));
  90.     int right = int(std::round(dw + 0.1f));
  91.     params[0] = ratio[0];
  92.     params[1] = ratio[1];
  93.     params[2] = left;
  94.     params[3] = top;
  95.     cv::copyMakeBorder(outImage, outImage, top, bottom, left, right, cv::BORDER_CONSTANT, color);
  96. }
  97. void GetMask(const int* const _seg_params, const float& rectConfidenceThreshold, const cv::Mat& maskProposals, const cv::Mat& mask_protos, const cv::Vec4d& params, const cv::Size& srcImgShape, std::vector<DCSP_RESULT>& output) {
  98.     int _segChannels = *_seg_params;
  99.     int _segHeight = *(_seg_params + 1);
  100.     int _segWidth = *(_seg_params + 2);
  101.     int _netHeight = *(_seg_params + 3);
  102.     int _netWidth = *(_seg_params + 4);
  103.     cv::Mat protos = mask_protos.reshape(0, { _segChannels,_segWidth * _segHeight });
  104.     cv::Mat matmulRes = (maskProposals * protos).t();
  105.     cv::Mat masks = matmulRes.reshape(output.size(), { _segHeight,_segWidth });
  106.     std::vector<cv::Mat> maskChannels;
  107.     split(masks, maskChannels);
  108.     for (int i = 0; i < output.size(); ++i) {
  109.         cv::Mat dest, mask;
  110.         //sigmoid
  111.         cv::exp(-maskChannels[i], dest);
  112.         dest = 1.0 / (1.0 + dest);
  113.         cv::Rect roi(int(params[2] / _netWidth * _segWidth), int(params[3] / _netHeight * _segHeight), int(_segWidth - params[2] / 2), int(_segHeight - params[3] / 2));
  114.         dest = dest(roi);
  115.         cv::resize(dest, mask, srcImgShape, cv::INTER_NEAREST);
  116.         //crop
  117.         cv::Rect temp_rect = output[i].box;
  118.         mask = mask(temp_rect) > rectConfidenceThreshold;
  119.         output[i].boxMask = mask;
  120.     }
  121. }
  122. void DCSP_CORE::DrawPred(cv::Mat& img, std::vector<DCSP_RESULT>& result) {
  123.     int detections = result.size();
  124.     std::cout << "Number of detections:" << detections << std::endl;
  125.     cv::Mat mask = img.clone();
  126.     for (int i = 0; i < detections; ++i)
  127.     {
  128.         DCSP_RESULT detection = result[i];
  129.         cv::Rect box = detection.box;
  130.         cv::Scalar color = detection.color;
  131.         // Detection box
  132.         cv::rectangle(img, box, color, 2);
  133.         mask(detection.box).setTo(color, detection.boxMask);
  134.         // Detection box text
  135.         std::string classString = detection.className + ' ' + std::to_string(detection.confidence).substr(0, 4);
  136.         cv::Size textSize = cv::getTextSize(classString, cv::FONT_HERSHEY_DUPLEX, 1, 2, 0);
  137.         cv::Rect textBox(box.x, box.y - 40, textSize.width + 10, textSize.height + 20);
  138.         cv::rectangle(img, textBox, color, cv::FILLED);
  139.         cv::putText(img, classString, cv::Point(box.x + 5, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 0), 2, 0);
  140.     }
  141.     // Detection mask
  142.     if (RunSegmentation) cv::addWeighted(img, 0.5, mask, 0.5, 0, img); //将mask加在原图上面
  143.     cv::imshow("Inference", img);
  144.     cv::imwrite("out.bmp", img);
  145.     cv::waitKey();
  146.     cv::destroyWindow("Inference");
  147. }
  148. char* DCSP_CORE::CreateSession(DCSP_INIT_PARAM& iParams) {
  149.     char* Ret = RET_OK;
  150.     std::regex pattern("[\u4e00-\u9fa5]");
  151.     bool result = std::regex_search(iParams.ModelPath, pattern);
  152.     if (result) {
  153.         char str_tmp[] = "[DCSP_ONNX]:Model path error.Change your model path without chinese characters.";
  154.         Ret = str_tmp;
  155.         std::cout << Ret << std::endl;
  156.         return Ret;
  157.     }
  158.     try {
  159.         modelConfidenceThreshold = iParams.modelConfidenceThreshold;
  160.         rectConfidenceThreshold = iParams.RectConfidenceThreshold;
  161.         iouThreshold = iParams.iouThreshold;
  162.         imgSize = iParams.imgSize;
  163.         modelType = iParams.ModelType;
  164.         env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "Yolo");
  165.         Ort::SessionOptions sessionOption;
  166.         if (iParams.CudaEnable) {
  167.             cudaEnable = iParams.CudaEnable;
  168.             OrtCUDAProviderOptions cudaOption;
  169.             cudaOption.device_id = 0;
  170.             sessionOption.AppendExecutionProvider_CUDA(cudaOption);
  171.         }
  172.         sessionOption.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
  173.         sessionOption.SetIntraOpNumThreads(iParams.IntraOpNumThreads);
  174.         sessionOption.SetLogSeverityLevel(iParams.LogSeverityLevel);
  175. #ifdef _WIN32
  176.         int ModelPathSize = MultiByteToWideChar(CP_UTF8, 0, iParams.ModelPath.c_str(), static_cast<int>(iParams.ModelPath.length()), nullptr, 0);
  177.         wchar_t* wide_cstr = new wchar_t[ModelPathSize + 1];
  178.         MultiByteToWideChar(CP_UTF8, 0, iParams.ModelPath.c_str(), static_cast<int>(iParams.ModelPath.length()), wide_cstr, ModelPathSize);
  179.         wide_cstr[ModelPathSize] = L'\0';
  180.         const wchar_t* modelPath = wide_cstr;
  181. #else
  182.         const char* modelPath = iParams.ModelPath.c_str();
  183. #endif // _WIN32
  184.         session = new Ort::Session(env, modelPath, sessionOption);
  185.         Ort::AllocatorWithDefaultOptions allocator;
  186.         size_t inputNodesNum = session->GetInputCount();
  187.         for (size_t i = 0; i < inputNodesNum; i++) {
  188.             Ort::AllocatedStringPtr input_node_name = session->GetInputNameAllocated(i, allocator);
  189.             char* temp_buf = new char[50];
  190.             strcpy(temp_buf, input_node_name.get());
  191.             inputNodeNames.push_back(temp_buf);
  192.         }
  193.         size_t OutputNodesNum = session->GetOutputCount();
  194.         for (size_t i = 0; i < OutputNodesNum; i++) {
  195.             Ort::AllocatedStringPtr output_node_name = session->GetOutputNameAllocated(i, allocator);
  196.             char* temp_buf = new char[10];
  197.             strcpy(temp_buf, output_node_name.get());
  198.             outputNodeNames.push_back(temp_buf);
  199.         }
  200.         if (outputNodeNames.size() == 2) RunSegmentation = true;
  201.         options = Ort::RunOptions{ nullptr };
  202.         WarmUpSession();
  203.         return RET_OK;
  204.     }
  205.     catch (const std::exception& e) {
  206.         const char* str1 = "[DCSP_ONNX]:";
  207.         const char* str2 = e.what();
  208.         std::string result = std::string(str1) + std::string(str2);
  209.         char* merged = new char[result.length() + 1];
  210.         std::strcpy(merged, result.c_str());
  211.         std::cout << merged << std::endl;
  212.         delete[] merged;
  213.         char str_tmps[] = "[DCSP_ONNX]:Create session failed.";
  214.         char* strs = str_tmps;
  215.         return strs;
  216.     }
  217. }
  218. char* DCSP_CORE::RunSession(cv::Mat& iImg, std::vector<DCSP_RESULT>& oResult) {
  219. #ifdef benchmark
  220.     clock_t starttime_1 = clock();
  221. #endif // benchmark
  222.     char* Ret = RET_OK;
  223.     cv::Mat processedImg;
  224.     cv::Vec4d params;
  225.     //resize图片尺寸,PreProcess是直接resize,LetterBox有padding操作
  226.     //PreProcess(iImg, imgSize, processedImg);
  227.     LetterBox(iImg, processedImg, params, cv::Size(imgSize.at(1), imgSize.at(0)));
  228.     if (modelType < 4) {
  229.         float* blob = new float[processedImg.total() * 3];
  230.         BlobFromImage(processedImg, blob);
  231.         std::vector<int64_t> inputNodeDims = { 1, 3, imgSize.at(0), imgSize.at(1) };
  232.         TensorProcess(starttime_1, params, iImg, blob, inputNodeDims, oResult);
  233.     }
  234.     else {
  235. #ifdef USE_CUDA
  236.         half* blob = new half[processedImg.total() * 3];
  237.         BlobFromImage(processedImg, blob);
  238.         std::vector<int64_t> inputNodeDims = { 1,3,imgSize.at(0),imgSize.at(1) };
  239.         TensorProcess(starttime_1, params, iImg, blob, inputNodeDims, oResult);
  240. #endif
  241.     }
  242.     return Ret;
  243. }
  244. template<typename N>
  245. char* DCSP_CORE::TensorProcess(clock_t& starttime_1, cv::Vec4d& params, cv::Mat& iImg, N* blob, std::vector<int64_t>& inputNodeDims, std::vector<DCSP_RESULT>& oResult) {
  246.     Ort::Value inputTensor = Ort::Value::CreateTensor<typename std::remove_pointer<N>::type>(
  247.         Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU), blob, 3 * imgSize.at(0) * imgSize.at(1), inputNodeDims.data(), inputNodeDims.size());
  248. #ifdef benchmark
  249.     clock_t starttime_2 = clock();
  250. #endif // benchmark
  251.     auto outputTensor = session->Run(options, inputNodeNames.data(), &inputTensor, 1, outputNodeNames.data(), outputNodeNames.size());
  252. #ifdef benchmark
  253.     clock_t starttime_3 = clock();
  254. #endif // benchmark
  255.     std::vector<int64_t> _outputTensorShape;
  256.     _outputTensorShape = outputTensor[0].GetTensorTypeAndShapeInfo().GetShape();
  257.     //auto output = outputTensor[0].GetTensorMutableData<typename std::remove_pointer<N>::type>();
  258.     N* output = outputTensor[0].GetTensorMutableData<N>();
  259.     delete blob;
  260.     // yolov5 has an output of shape (batchSize, 25200, 85) (Num classes + box[x,y,w,h] + confidence[c])
  261.     // yolov8 has an output of shape (batchSize, 84,  8400) (Num classes + box[x,y,w,h])
  262.     // yolov5
  263.     int dimensions = _outputTensorShape[1];
  264.     int rows = _outputTensorShape[2];
  265.     cv::Mat rowData;
  266.     if (modelType < 3)
  267.         rowData = cv::Mat(dimensions, rows, CV_32F, output);
  268.     else
  269.         rowData = cv::Mat(dimensions, rows, CV_16S, output);
  270.     // yolov8
  271.     if (rows > dimensions) {
  272.         dimensions = _outputTensorShape[2];
  273.         rows = _outputTensorShape[1];
  274.         rowData = rowData.t();
  275.     }
  276.     std::vector<int> class_ids;
  277.     std::vector<float> confidences;
  278.     std::vector<cv::Rect> boxes;
  279.     std::vector<std::vector<float>> picked_proposals;
  280.     N* data = (N*)rowData.data;
  281.     for (int i = 0; i < dimensions; ++i) {
  282.         switch (modelType) {
  283.         case 0://V5_ORIGIN_FP32
  284.         case 7://V5_ORIGIN_FP16
  285.         {
  286.             N confidence = data[4];
  287.             if (confidence >= modelConfidenceThreshold)
  288.             {
  289.                 cv::Mat scores;
  290.                 if (modelType < 3) scores = cv::Mat(1, classes.size(), CV_32FC1, data + 5);
  291.                 else scores = cv::Mat(1, classes.size(), CV_16SC1, data + 5);
  292.                 cv::Point class_id;
  293.                 double max_class_score;
  294.                 minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
  295.                 max_class_score = *(data + 5 + class_id.x) * confidence;
  296.                 if (max_class_score > rectConfidenceThreshold)
  297.                 {
  298.                     if (RunSegmentation) {
  299.                         int _segChannels = outputTensor[1].GetTensorTypeAndShapeInfo().GetShape()[1];
  300.                         std::vector<float> temp_proto(data + classes.size() + 5, data + classes.size() + 5 + _segChannels);
  301.                         picked_proposals.push_back(temp_proto);
  302.                     }
  303.                     confidences.push_back(confidence);
  304.                     class_ids.push_back(class_id.x);
  305.                     float x = (data[0] - params[2]) / params[0];
  306.                     float y = (data[1] - params[3]) / params[1];
  307.                     float w = data[2] / params[0];
  308.                     float h = data[3] / params[1];
  309.                     int left = MAX(round(x - 0.5 * w + 0.5), 0);
  310.                     int top = MAX(round(y - 0.5 * h + 0.5), 0);
  311.                     if ((left + w) > iImg.cols) { w = iImg.cols - left; }
  312.                     if ((top + h) > iImg.rows) { h = iImg.rows - top; }
  313.                     boxes.emplace_back(cv::Rect(left, top, int(w), int(h)));
  314.                 }
  315.             }
  316.             break;
  317.         }
  318.         case 1://V8_ORIGIN_FP32
  319.         case 4://V8_ORIGIN_FP16
  320.         {
  321.             cv::Mat scores;
  322.             if (modelType < 3) scores = cv::Mat(1, classes.size(), CV_32FC1, data + 4);
  323.             else scores = cv::Mat(1, classes.size(), CV_16SC1, data + 4);
  324.             cv::Point class_id;
  325.             double maxClassScore;
  326.             cv::minMaxLoc(scores, 0, &maxClassScore, 0, &class_id);
  327.             maxClassScore = *(data + 4 + class_id.x);
  328.             if (maxClassScore > rectConfidenceThreshold) {
  329.                 if (RunSegmentation) {
  330.                     int _segChannels = outputTensor[1].GetTensorTypeAndShapeInfo().GetShape()[1];
  331.                     std::vector<float> temp_proto(data + classes.size() + 4, data + classes.size() + 4 + _segChannels);
  332.                     picked_proposals.push_back(temp_proto);
  333.                 }
  334.                 confidences.push_back(maxClassScore);
  335.                 class_ids.push_back(class_id.x);
  336.                 float x = (data[0] - params[2]) / params[0];
  337.                 float y = (data[1] - params[3]) / params[1];
  338.                 float w = data[2] / params[0];
  339.                 float h = data[3] / params[1];
  340.                 int left = MAX(round(x - 0.5 * w + 0.5), 0);
  341.                 int top = MAX(round(y - 0.5 * h + 0.5), 0);
  342.                 if ((left + w) > iImg.cols) { w = iImg.cols - left; }
  343.                 if ((top + h) > iImg.rows) { h = iImg.rows - top; }
  344.                 boxes.emplace_back(cv::Rect(left, top, int(w), int(h)));
  345.             }
  346.             break;
  347.         }
  348.         }
  349.         data += rows;
  350.     }
  351.     std::vector<int> nmsResult;
  352.     cv::dnn::NMSBoxes(boxes, confidences, rectConfidenceThreshold, iouThreshold, nmsResult);
  353.     std::vector<std::vector<float>> temp_mask_proposals;
  354.     for (int i = 0; i < nmsResult.size(); ++i) {
  355.         int idx = nmsResult[i];
  356.         DCSP_RESULT result;
  357.         result.classId = class_ids[idx];
  358.         result.confidence = confidences[idx];
  359.         result.box = boxes[idx];
  360.         result.className = classes[result.classId];
  361.         std::random_device rd;
  362.         std::mt19937 gen(rd());
  363.         std::uniform_int_distribution<int> dis(100, 255);
  364.         result.color = cv::Scalar(dis(gen), dis(gen), dis(gen));
  365.         if (result.box.width != 0 && result.box.height != 0) oResult.push_back(result);
  366.         if (RunSegmentation) temp_mask_proposals.push_back(picked_proposals[idx]);
  367.     }
  368.     if (RunSegmentation) {
  369.         cv::Mat mask_proposals;
  370.         for (int i = 0; i < temp_mask_proposals.size(); ++i)
  371.             mask_proposals.push_back(cv::Mat(temp_mask_proposals[i]).t());
  372.         std::vector<int64_t> _outputMaskTensorShape;
  373.         _outputMaskTensorShape = outputTensor[1].GetTensorTypeAndShapeInfo().GetShape();
  374.         int _segChannels = _outputMaskTensorShape[1];
  375.         int _segWidth = _outputMaskTensorShape[2];
  376.         int _segHeight = _outputMaskTensorShape[3];
  377.         N* pdata = outputTensor[1].GetTensorMutableData<N>();
  378.         std::vector<float> mask(pdata, pdata + _segChannels * _segWidth * _segHeight);
  379.         int _seg_params[5] = { _segChannels, _segWidth, _segHeight, inputNodeDims[2], inputNodeDims[3] };
  380.         cv::Mat mask_protos = cv::Mat(mask);
  381.         GetMask(_seg_params, rectConfidenceThreshold, mask_proposals, mask_protos, params, iImg.size(), oResult);
  382.     }
  383. #ifdef benchmark
  384.     clock_t starttime_4 = clock();
  385.     double pre_process_time = (double)(starttime_2 - starttime_1) / CLOCKS_PER_SEC * 1000;
  386.     double process_time = (double)(starttime_3 - starttime_2) / CLOCKS_PER_SEC * 1000;
  387.     double post_process_time = (double)(starttime_4 - starttime_3) / CLOCKS_PER_SEC * 1000;
  388.     if (cudaEnable) {
  389.         std::cout << "[DCSP_ONNX(CUDA)]: " << pre_process_time << "ms pre-process, " << process_time
  390.             << "ms inference, " << post_process_time << "ms post-process." << std::endl;
  391.     }
  392.     else {
  393.         std::cout << "[DCSP_ONNX(CPU)]: " << pre_process_time << "ms pre-process, " << process_time
  394.             << "ms inference, " << post_process_time << "ms post-process." << std::endl;
  395.     }
  396. #endif // benchmark
  397.     return RET_OK;
  398. }
  399. char* DCSP_CORE::WarmUpSession() {
  400.     clock_t starttime_1 = clock();
  401.     cv::Mat iImg = cv::Mat(cv::Size(imgSize.at(0), imgSize.at(1)), CV_8UC3);
  402.     cv::Mat processedImg;
  403.     cv::Vec4d params;
  404.     //resize图片尺寸,PreProcess是直接resize,LetterBox有padding操作
  405.     //PreProcess(iImg, imgSize, processedImg);
  406.     LetterBox(iImg, processedImg, params, cv::Size(imgSize.at(1), imgSize.at(0)));
  407.     if (modelType < 4) {
  408.         float* blob = new float[iImg.total() * 3];
  409.         BlobFromImage(processedImg, blob);
  410.         std::vector<int64_t> YOLO_input_node_dims = { 1, 3, imgSize.at(0), imgSize.at(1) };
  411.         Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
  412.             Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU), blob, 3 * imgSize.at(0) * imgSize.at(1),
  413.             YOLO_input_node_dims.data(), YOLO_input_node_dims.size());
  414.         auto output_tensors = session->Run(options, inputNodeNames.data(), &input_tensor, 1, outputNodeNames.data(), outputNodeNames.size());
  415.         delete[] blob;
  416.         clock_t starttime_4 = clock();
  417.         double post_process_time = (double)(starttime_4 - starttime_1) / CLOCKS_PER_SEC * 1000;
  418.         if (cudaEnable) {
  419.             std::cout << "[DCSP_ONNX(CUDA)]: " << "Cuda warm-up cost " << post_process_time << " ms. " << std::endl;
  420.         }
  421.     }
  422.     else {
  423. #ifdef USE_CUDA
  424.         half* blob = new half[iImg.total() * 3];
  425.         BlobFromImage(processedImg, blob);
  426.         std::vector<int64_t> YOLO_input_node_dims = { 1,3,imgSize.at(0),imgSize.at(1) };
  427.         Ort::Value input_tensor = Ort::Value::CreateTensor<half>(Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU), blob, 3 * imgSize.at(0) * imgSize.at(1), YOLO_input_node_dims.data(), YOLO_input_node_dims.size());
  428.         auto output_tensors = session->Run(options, inputNodeNames.data(), &input_tensor, 1, outputNodeNames.data(), outputNodeNames.size());
  429.         delete[] blob;
  430.         clock_t starttime_4 = clock();
  431.         double post_process_time = (double)(starttime_4 - starttime_1) / CLOCKS_PER_SEC * 1000;
  432.         if (cudaEnable)
  433.         {
  434.             std::cout << "[DCSP_ONNX(CUDA)]: " << "Cuda warm-up cost " << post_process_time << " ms. " << std::endl;
  435.         }
  436. #endif
  437.     }
  438.     return RET_OK;
  439. }
复制代码
yolov5v8_dnn.h
  1. #ifndef YOLOV5V8_DNN_H
  2. #define YOLOV5V8_DNN_H
  3. // Cpp native
  4. #include <fstream>
  5. #include <vector>
  6. #include <string>
  7. #include <random>
  8. // OpenCV / DNN / Inference
  9. #include <opencv2/imgproc.hpp>
  10. #include <opencv2/opencv.hpp>
  11. #include <opencv2/dnn.hpp>
  12. struct Detection
  13. {
  14.     int class_id{ 0 };
  15.     std::string className{};
  16.     float confidence{ 0.0 };
  17.     cv::Scalar color{};
  18.     cv::Rect box{};
  19.     cv::Mat boxMask;
  20. };
  21. class Inference
  22. {
  23. public:
  24.     Inference(const std::string& onnxModelPath, const cv::Size& modelInputShape = { 640, 640 }, const std::string& classesTxtFile = "", const bool& runWithCuda = true);
  25.     std::vector<Detection> runInference(const cv::Mat& input);
  26.     void DrawPred(cv::Mat& img, std::vector<Detection>& result);
  27. private:
  28.     void loadClassesFromFile();
  29.     void loadOnnxNetwork();
  30.     void LetterBox(const cv::Mat& image, cv::Mat& outImage,
  31.         cv::Vec4d& params, //[ratio_x,ratio_y,dw,dh]
  32.         const cv::Size& newShape = cv::Size(640, 640),
  33.         bool autoShape = false,
  34.         bool scaleFill = false,
  35.         bool scaleUp = true,
  36.         int stride = 32,
  37.         const cv::Scalar& color = cv::Scalar(114, 114, 114));
  38.     void GetMask(const cv::Mat& maskProposals, const cv::Mat& mask_protos, const cv::Vec4d& params, const cv::Size& srcImgShape, std::vector<Detection>& output);
  39. private:
  40.     std::string modelPath{};
  41.     bool cudaEnabled{};
  42.     cv::Size2f modelShape{};
  43.     bool RunSegmentation = false;
  44.     float modelConfidenceThreshold{ 0.25 };
  45.     float modelScoreThreshold{ 0.45 };
  46.     float modelNMSThreshold{ 0.50 };
  47.     bool letterBoxForSquare = true;
  48.     cv::dnn::Net net;
  49.     std::string classesPath{};
  50.     std::vector<std::string> classes{ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant",
  51.         "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
  52.         "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
  53.         "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot",
  54.         "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard",
  55.         "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush" };
  56. };
  57. #endif // YOLOV5V8_DNN_H
复制代码
yolov5v8_ort.h
  1. #pragma once
  2. #define    RET_OK nullptr
  3. #define    USE_CUDA
  4. #ifdef _WIN32
  5. #include <Windows.h>
  6. #include <direct.h>
  7. #include <io.h>
  8. #endif
  9. #include <string>
  10. #include <vector>
  11. #include <cstdio>
  12. #include <opencv2/opencv.hpp>
  13. #include "onnxruntime_cxx_api.h"
  14. #ifdef USE_CUDA
  15. #include <cuda_fp16.h>
  16. #endif
  17. enum MODEL_TYPE {
  18.     //FLOAT32 MODEL
  19.     YOLO_ORIGIN_V5 = 0,//support
  20.     YOLO_ORIGIN_V8 = 1,//support
  21.     YOLO_POSE_V8 = 2,
  22.     YOLO_CLS_V8 = 3,
  23.     YOLO_ORIGIN_V8_HALF = 4,//support
  24.     YOLO_POSE_V8_HALF = 5,
  25.     YOLO_CLS_V8_HALF = 6,
  26.     YOLO_ORIGIN_V5_HALF = 7 //support
  27. };
  28. typedef struct _DCSP_INIT_PARAM {
  29.     std::string ModelPath;
  30.     MODEL_TYPE ModelType = YOLO_ORIGIN_V8;
  31.     std::vector<int> imgSize = { 640, 640 };
  32.     float modelConfidenceThreshold = 0.25;
  33.     float RectConfidenceThreshold = 0.6;
  34.     float iouThreshold = 0.5;
  35.     bool CudaEnable = false;
  36.     int LogSeverityLevel = 3;
  37.     int IntraOpNumThreads = 1;
  38. } DCSP_INIT_PARAM;
  39. typedef struct _DCSP_RESULT {
  40.     int classId;
  41.     std::string className;
  42.     float confidence;
  43.     cv::Rect box;
  44.     cv::Mat boxMask;       //矩形框内mask
  45.     cv::Scalar color;
  46. } DCSP_RESULT;
  47. class DCSP_CORE {
  48. public:
  49.     DCSP_CORE();
  50.     ~DCSP_CORE();
  51. public:
  52.     void DrawPred(cv::Mat& img, std::vector<DCSP_RESULT>& result);
  53.     char* CreateSession(DCSP_INIT_PARAM& iParams);
  54.     char* RunSession(cv::Mat& iImg, std::vector<DCSP_RESULT>& oResult);
  55.     char* WarmUpSession();
  56.     template<typename N>
  57.     char* TensorProcess(clock_t& starttime_1, cv::Vec4d& params, cv::Mat& iImg, N* blob, std::vector<int64_t>& inputNodeDims, std::vector<DCSP_RESULT>& oResult);
  58.     std::vector<std::string> classes{ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant",
  59.     "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
  60.     "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
  61.     "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot",
  62.     "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard",
  63.     "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush" };
  64. private:
  65.     Ort::Env env;
  66.     Ort::Session* session;
  67.     bool cudaEnable;
  68.     Ort::RunOptions options;
  69.     bool RunSegmentation = false;
  70.     std::vector<const char*> inputNodeNames;
  71.     std::vector<const char*> outputNodeNames;
  72.     MODEL_TYPE modelType;
  73.     std::vector<int> imgSize;
  74.     float modelConfidenceThreshold;
  75.     float rectConfidenceThreshold;
  76.     float iouThreshold;
  77. };
复制代码
3.geotpt文件的设置

geotpt文件的设置比较简朴,我们只须要写两个文件放入我们的工程就行,代码如下:
getopt.h
  1. # ifndef __GETOPT_H_
  2. # define __GETOPT_H_
  3. # ifdef _GETOPT_API
  4. #     undef _GETOPT_API
  5. # endif
  6. //------------------------------------------------------------------------------
  7. # if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
  8. #     error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT \
  9. can only be used individually"
  10. # elif defined(STATIC_GETOPT)
  11. #     pragma message("Warning static builds of getopt violate the Lesser GNU \
  12. Public License")
  13. #     define _GETOPT_API
  14. # elif defined(EXPORTS_GETOPT)
  15. #     pragma message("Exporting getopt library")
  16. #     define _GETOPT_API __declspec(dllexport)
  17. # else
  18. #     pragma message("Importing getopt library")
  19. #     define _GETOPT_API __declspec(dllimport)
  20. # endif
  21. # include <tchar.h>
  22. // Standard GNU options
  23. # define null_argument           0 /*Argument Null*/
  24. # define no_argument             0 /*Argument Switch Only*/
  25. # define required_argument       1 /*Argument Required*/
  26. # define optional_argument       2 /*Argument Optional*/
  27. // Shorter Versions of options
  28. # define ARG_NULL 0 /*Argument Null*/
  29. # define ARG_NONE 0 /*Argument Switch Only*/
  30. # define ARG_REQ  1 /*Argument Required*/
  31. # define ARG_OPT  2 /*Argument Optional*/
  32. // Change behavior for C\C++
  33. # ifdef __cplusplus
  34. #     define _BEGIN_EXTERN_C extern "C" {
  35. #     define _END_EXTERN_C }
  36. #     define _GETOPT_THROW throw()
  37. # else
  38. #     define _BEGIN_EXTERN_C
  39. #     define _END_EXTERN_C
  40. #     define _GETOPT_THROW
  41. # endif
  42. _BEGIN_EXTERN_C
  43. extern _GETOPT_API TCHAR* optarg;
  44. extern _GETOPT_API int    optind;
  45. extern _GETOPT_API int    opterr;
  46. extern _GETOPT_API int    optopt;
  47. struct option
  48. {
  49.     /* The predefined macro variable __STDC__ is defined for C++, and it has the in-
  50.        teger value 0 when it is used in an #if statement, indicating that the C++ l-
  51.        anguage is not a proper superset of C, and that the compiler does not confor-
  52.        m to C. In C, __STDC__ has the integer value 1. */
  53. # if defined (__STDC__) && __STDC__
  54.     const TCHAR* name;
  55. # else
  56.     TCHAR* name;
  57. # endif
  58.     int has_arg;
  59.     int* flag;
  60.     TCHAR val;
  61. };
  62. extern _GETOPT_API int getopt(int argc, TCHAR* const* argv
  63.     , const TCHAR* optstring) _GETOPT_THROW;
  64. extern _GETOPT_API int getopt_long
  65. (int ___argc, TCHAR* const* ___argv
  66.     , const TCHAR* __shortopts
  67.     , const struct option* __longopts
  68.     , int* __longind) _GETOPT_THROW;
  69. extern _GETOPT_API int getopt_long_only
  70. (int ___argc, TCHAR* const* ___argv
  71.     , const TCHAR* __shortopts
  72.     , const struct option* __longopts
  73.     , int* __longind) _GETOPT_THROW;
  74. // harly.he add for reentrant 12.09/2013
  75. extern _GETOPT_API void getopt_reset() _GETOPT_THROW;
  76. _END_EXTERN_C
  77. // Undefine so the macros are not included
  78. # undef _BEGIN_EXTERN_C
  79. # undef _END_EXTERN_C
  80. # undef _GETOPT_THROW
  81. # undef _GETOPT_API
  82. # endif  // __GETOPT_H_
复制代码
getopt.c
  1. # ifndef _CRT_SECURE_NO_WARNINGS
  2. #     define _CRT_SECURE_NO_WARNINGS
  3. # endif
  4. # include <stdlib.h>
  5. # include <stdio.h>
  6. # include <tchar.h>
  7. # include "getopt.h"
  8. # ifdef __cplusplus
  9. #     define _GETOPT_THROW throw()
  10. # else
  11. #     define _GETOPT_THROW
  12. # endif
  13. enum ENUM_ORDERING
  14. {
  15.     REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
  16. };
  17. struct _getopt_data
  18. {
  19.     int     optind;
  20.     int     opterr;
  21.     int     optopt;
  22.     TCHAR* optarg;
  23.     int     __initialized;
  24.     TCHAR* __nextchar;
  25.     int     __ordering;
  26.     int     __posixly_correct;
  27.     int     __first_nonopt;
  28.     int     __last_nonopt;
  29. };
  30. static struct _getopt_data  getopt_data = { 0, 0, 0, NULL, 0, NULL, 0, 0, 0, 0 };
  31. TCHAR* optarg = NULL;
  32. int     optind = 1;
  33. int     opterr = 1;
  34. int     optopt = _T('?');
  35. static void exchange(TCHAR** argv, struct _getopt_data* d)
  36. {
  37.     int     bottom = d->__first_nonopt;
  38.     int     middle = d->__last_nonopt;
  39.     int     top = d->optind;
  40.     TCHAR* tem;
  41.     while (top > middle && middle > bottom)
  42.     {
  43.         if (top - middle > middle - bottom)
  44.         {
  45.             int len = middle - bottom;
  46.             register int i;
  47.             for (i = 0; i < len; i++)
  48.             {
  49.                 tem = argv[bottom + i];
  50.                 argv[bottom + i] = argv[top - (middle - bottom) + i];
  51.                 argv[top - (middle - bottom) + i] = tem;
  52.             }
  53.             top -= len;
  54.         }
  55.         else
  56.         {
  57.             int len = top - middle;
  58.             register int i;
  59.             for (i = 0; i < len; i++)
  60.             {
  61.                 tem = argv[bottom + i];
  62.                 argv[bottom + i] = argv[middle + i];
  63.                 argv[middle + i] = tem;
  64.             }
  65.             bottom += len;
  66.         }
  67.     }
  68.     d->__first_nonopt += (d->optind - d->__last_nonopt);
  69.     d->__last_nonopt = d->optind;
  70. }
  71. static const TCHAR* _getopt_initialize(const TCHAR* optstring
  72.     , struct _getopt_data* d
  73.     , int posixly_correct)
  74. {
  75.     d->__first_nonopt = d->__last_nonopt = d->optind;
  76.     d->__nextchar = NULL;
  77.     d->__posixly_correct = posixly_correct
  78.         | !!_tgetenv(_T("POSIXLY_CORRECT"));
  79.     if (optstring[0] == _T('-'))
  80.     {
  81.         d->__ordering = RETURN_IN_ORDER;
  82.         ++optstring;
  83.     }
  84.     else if (optstring[0] == _T('+'))
  85.     {
  86.         d->__ordering = REQUIRE_ORDER;
  87.         ++optstring;
  88.     }
  89.     else if (d->__posixly_correct)
  90.     {
  91.         d->__ordering = REQUIRE_ORDER;
  92.     }
  93.     else
  94.     {
  95.         d->__ordering = PERMUTE;
  96.     }
  97.     return optstring;
  98. }
  99. int _getopt_internal_r(int argc
  100.     , TCHAR* const* argv
  101.     , const TCHAR* optstring
  102.     , const struct option* longopts
  103.     , int* longind
  104.     , int long_only
  105.     , struct _getopt_data* d
  106.     , int posixly_correct)
  107. {
  108.     int print_errors = d->opterr;
  109.     if (argc < 1)
  110.     {
  111.         return -1;
  112.     }
  113.     d->optarg = NULL;
  114.     if (d->optind == 0 || !d->__initialized)
  115.     {
  116.         if (d->optind == 0)
  117.         {
  118.             d->optind = 1;
  119.         }
  120.         optstring = _getopt_initialize(optstring, d, posixly_correct);
  121.         d->__initialized = 1;
  122.     }
  123.     else if (optstring[0] == _T('-') || optstring[0] == _T('+'))
  124.     {
  125.         optstring++;
  126.     }
  127.     if (optstring[0] == _T(':'))
  128.     {
  129.         print_errors = 0;
  130.     }
  131.     if (d->__nextchar == NULL || *d->__nextchar == _T('\0'))
  132.     {
  133.         if (d->__last_nonopt > d->optind)
  134.         {
  135.             d->__last_nonopt = d->optind;
  136.         }
  137.         if (d->__first_nonopt > d->optind)
  138.         {
  139.             d->__first_nonopt = d->optind;
  140.         }
  141.         if (d->__ordering == PERMUTE)
  142.         {
  143.             if (d->__first_nonopt != d->__last_nonopt
  144.                 && d->__last_nonopt != d->optind)
  145.             {
  146.                 exchange((TCHAR**)argv, d);
  147.             }
  148.             else if (d->__last_nonopt != d->optind)
  149.             {
  150.                 d->__first_nonopt = d->optind;
  151.             }
  152.             while (d->optind
  153.                 < argc
  154.                 && (argv[d->optind][0] != _T('-')
  155.                     || argv[d->optind][1] == _T('\0')))
  156.             {
  157.                 d->optind++;
  158.             }
  159.             d->__last_nonopt = d->optind;
  160.         }
  161.         if (d->optind != argc && !_tcscmp(argv[d->optind], _T("--")))
  162.         {
  163.             d->optind++;
  164.             if (d->__first_nonopt != d->__last_nonopt
  165.                 && d->__last_nonopt != d->optind)
  166.             {
  167.                 exchange((TCHAR**)argv, d);
  168.             }
  169.             else if (d->__first_nonopt == d->__last_nonopt)
  170.             {
  171.                 d->__first_nonopt = d->optind;
  172.             }
  173.             d->__last_nonopt = argc;
  174.             d->optind = argc;
  175.         }
  176.         if (d->optind == argc)
  177.         {
  178.             if (d->__first_nonopt != d->__last_nonopt)
  179.             {
  180.                 d->optind = d->__first_nonopt;
  181.             }
  182.             return -1;
  183.         }
  184.         if ((argv[d->optind][0] != _T('-')
  185.             || argv[d->optind][1] == _T('\0')))
  186.         {
  187.             if (d->__ordering == REQUIRE_ORDER)
  188.             {
  189.                 return -1;
  190.             }
  191.             d->optarg = argv[d->optind++];
  192.             return 1;
  193.         }
  194.         d->__nextchar = (argv[d->optind]
  195.             + 1 + (longopts != NULL
  196.                 && argv[d->optind][1] == _T('-')));
  197.     }
  198.     if (longopts != NULL
  199.         && (argv[d->optind][1] == _T('-')
  200.             || (long_only && (argv[d->optind][2]
  201.                 || !_tcschr(optstring, argv[d->optind][1]))
  202.                 )
  203.             )
  204.         )
  205.     {
  206.         TCHAR* nameend;
  207.         const struct option* p;
  208.         const struct option* pfound = NULL;
  209.         int                     exact = 0;
  210.         int                     ambig = 0;
  211.         int                     indfound = -1;
  212.         int                     option_index;
  213.         for (nameend = d->__nextchar;
  214.             *nameend && *nameend != _T('=');
  215.             nameend++)
  216.             ;
  217.         for (p = longopts, option_index = 0; p->name; p++, option_index++)
  218.         {
  219.             if (!_tcsncmp(p->name, d->__nextchar, nameend - d->__nextchar))
  220.             {
  221.                 if ((unsigned int)(nameend - d->__nextchar)
  222.                     == (unsigned int)_tcslen(p->name))
  223.                 {
  224.                     pfound = p;
  225.                     indfound = option_index;
  226.                     exact = 1;
  227.                     break;
  228.                 }
  229.                 else if (pfound == NULL)
  230.                 {
  231.                     pfound = p;
  232.                     indfound = option_index;
  233.                 }
  234.                 else if (long_only
  235.                     || pfound->has_arg != p->has_arg
  236.                     || pfound->flag != p->flag
  237.                     || pfound->val != p->val)
  238.                 {
  239.                     ambig = 1;
  240.                 }
  241.             }
  242.         }
  243.         if (ambig && !exact)
  244.         {
  245.             if (print_errors)
  246.             {
  247.                 _ftprintf(stderr
  248.                     , _T("%s: option '%s' is ambiguous\n")
  249.                     , argv[0]
  250.                     , argv[d->optind]);
  251.             }
  252.             d->__nextchar += _tcslen(d->__nextchar);
  253.             d->optind++;
  254.             d->optopt = 0;
  255.             return _T('?');
  256.         }
  257.         if (pfound != NULL)
  258.         {
  259.             option_index = indfound;
  260.             d->optind++;
  261.             if (*nameend)
  262.             {
  263.                 if (pfound->has_arg)
  264.                 {
  265.                     d->optarg = nameend + 1;
  266.                 }
  267.                 else
  268.                 {
  269.                     if (print_errors)
  270.                     {
  271.                         if (argv[d->optind - 1][1] == _T('-'))
  272.                         {
  273.                             _ftprintf(stderr
  274.                                 , _T("%s: option '--%s' doesn't allow ")
  275.                                 _T("an argument\n")
  276.                                 , argv[0]
  277.                                 , pfound->name);
  278.                         }
  279.                         else
  280.                         {
  281.                             _ftprintf(stderr
  282.                                 , _T("%s: option '%c%s' doesn't allow ")
  283.                                 _T("an argument\n")
  284.                                 , argv[0]
  285.                                 , argv[d->optind - 1][0]
  286.                                 , pfound->name);
  287.                         }
  288.                     }
  289.                     d->__nextchar += _tcslen(d->__nextchar);
  290.                     d->optopt = pfound->val;
  291.                     return _T('?');
  292.                 }
  293.             }
  294.             else if (pfound->has_arg == 1)
  295.             {
  296.                 if (d->optind < argc)
  297.                 {
  298.                     d->optarg = argv[d->optind++];
  299.                 }
  300.                 else
  301.                 {
  302.                     if (print_errors)
  303.                     {
  304.                         _ftprintf(stderr
  305.                             , _T("%s: option '--%s' requires an ")
  306.                             _T("argument\n")
  307.                             , argv[0]
  308.                             , pfound->name);
  309.                     }
  310.                     d->__nextchar += _tcslen(d->__nextchar);
  311.                     d->optopt = pfound->val;
  312.                     return optstring[0] == _T(':') ? _T(':') : _T('?');
  313.                 }
  314.             }
  315.             d->__nextchar += _tcslen(d->__nextchar);
  316.             if (longind != NULL)
  317.             {
  318.                 *longind = option_index;
  319.             }
  320.             if (pfound->flag)
  321.             {
  322.                 *(pfound->flag) = pfound->val;
  323.                 return 0;
  324.             }
  325.             return pfound->val;
  326.         }
  327.         if (!long_only
  328.             || argv[d->optind][1]
  329.             == _T('-')
  330.             || _tcschr(optstring
  331.                 , *d->__nextchar)
  332.             == NULL)
  333.         {
  334.             if (print_errors)
  335.             {
  336.                 if (argv[d->optind][1] == _T('-'))
  337.                 {
  338.                     /* --option */
  339.                     _ftprintf(stderr
  340.                         , _T("%s: unrecognized option '--%s'\n")
  341.                         , argv[0]
  342.                         , d->__nextchar);
  343.                 }
  344.                 else
  345.                 {
  346.                     /* +option or -option */
  347.                     _ftprintf(stderr
  348.                         , _T("%s: unrecognized option '%c%s'\n")
  349.                         , argv[0]
  350.                         , argv[d->optind][0]
  351.                         , d->__nextchar);
  352.                 }
  353.             }
  354.             d->__nextchar = (TCHAR*)_T("");
  355.             d->optind++;
  356.             d->optopt = 0;
  357.             return _T('?');
  358.         }
  359.     }
  360.     {
  361.         TCHAR   c = *d->__nextchar++;
  362.         TCHAR* temp = (TCHAR*)_tcschr(optstring, c);
  363.         if (*d->__nextchar == _T('\0'))
  364.         {
  365.             ++d->optind;
  366.         }
  367.         if (temp == NULL || c == _T(':') || c == _T(';'))
  368.         {
  369.             if (print_errors)
  370.             {
  371.                 _ftprintf(stderr
  372.                     , _T("%s: invalid option -- '%c'\n")
  373.                     , argv[0]
  374.                     , c);
  375.             }
  376.             d->optopt = c;
  377.             return _T('?');
  378.         }
  379.         if (temp[0] == _T('W') && temp[1] == _T(';'))
  380.         {
  381.             TCHAR* nameend;
  382.             const struct option* p;
  383.             const struct option* pfound = NULL;
  384.             int                     exact = 0;
  385.             int                     ambig = 0;
  386.             int                     indfound = 0;
  387.             int                     option_index;
  388.             if (*d->__nextchar != _T('\0'))
  389.             {
  390.                 d->optarg = d->__nextchar;
  391.                 d->optind++;
  392.             }
  393.             else if (d->optind == argc)
  394.             {
  395.                 if (print_errors)
  396.                 {
  397.                     _ftprintf(stderr
  398.                         , _T("%s: option requires an argument -- '%c'\n")
  399.                         , argv[0]
  400.                         , c);
  401.                 }
  402.                 d->optopt = c;
  403.                 if (optstring[0] == _T(':'))
  404.                 {
  405.                     c = _T(':');
  406.                 }
  407.                 else
  408.                 {
  409.                     c = _T('?');
  410.                 }
  411.                 return c;
  412.             }
  413.             else
  414.             {
  415.                 d->optarg = argv[d->optind++];
  416.             }
  417.             for (d->__nextchar = nameend = d->optarg;
  418.                 *nameend && *nameend != _T('=');
  419.                 nameend++)
  420.                 ;
  421.             for (p = longopts, option_index = 0;
  422.                 p->name;
  423.                 p++, option_index++)
  424.             {
  425.                 if (!_tcsncmp(p->name
  426.                     , d->__nextchar
  427.                     , nameend - d->__nextchar))
  428.                 {
  429.                     if ((unsigned int)(nameend - d->__nextchar)
  430.                         == _tcslen(p->name))
  431.                     {
  432.                         pfound = p;
  433.                         indfound = option_index;
  434.                         exact = 1;
  435.                         break;
  436.                     }
  437.                     else if (pfound == NULL)
  438.                     {
  439.                         pfound = p;
  440.                         indfound = option_index;
  441.                     }
  442.                     else if (long_only
  443.                         || pfound->has_arg != p->has_arg
  444.                         || pfound->flag != p->flag
  445.                         || pfound->val != p->val)
  446.                     {
  447.                         ambig = 1;
  448.                     }
  449.                 }
  450.             }
  451.             if (ambig && !exact)
  452.             {
  453.                 if (print_errors)
  454.                 {
  455.                     _ftprintf(stderr
  456.                         , _T("%s: option '-W %s' is ambiguous\n")
  457.                         , argv[0]
  458.                         , d->optarg);
  459.                 }
  460.                 d->__nextchar += _tcslen(d->__nextchar);
  461.                 d->optind++;
  462.                 return _T('?');
  463.             }
  464.             if (pfound != NULL)
  465.             {
  466.                 option_index = indfound;
  467.                 if (*nameend)
  468.                 {
  469.                     if (pfound->has_arg)
  470.                     {
  471.                         d->optarg = nameend + 1;
  472.                     }
  473.                     else
  474.                     {
  475.                         if (print_errors)
  476.                         {
  477.                             _ftprintf(stderr
  478.                                 , _T("%s: option '-W %s' doesn't allow ")
  479.                                 _T("an argument\n")
  480.                                 , argv[0]
  481.                                 , pfound->name);
  482.                         }
  483.                         d->__nextchar += _tcslen(d->__nextchar);
  484.                         return _T('?');
  485.                     }
  486.                 }
  487.                 else if (pfound->has_arg == 1)
  488.                 {
  489.                     if (d->optind < argc)
  490.                     {
  491.                         d->optarg = argv[d->optind++];
  492.                     }
  493.                     else
  494.                     {
  495.                         if (print_errors)
  496.                         {
  497.                             _ftprintf(stderr
  498.                                 , _T("%s: option '-W %s' requires an ")
  499.                                 _T("argument\n")
  500.                                 , argv[0]
  501.                                 , pfound->name);
  502.                         }
  503.                         d->__nextchar += _tcslen(d->__nextchar);
  504.                         return optstring[0] == _T(':') ? _T(':') : _T('?');
  505.                     }
  506.                 }
  507.                 else
  508.                 {
  509.                     d->optarg = NULL;
  510.                 }
  511.                 d->__nextchar += _tcslen(d->__nextchar);
  512.                 if (longind != NULL)
  513.                 {
  514.                     *longind = option_index;
  515.                 }
  516.                 if (pfound->flag)
  517.                 {
  518.                     *(pfound->flag) = pfound->val;
  519.                     return 0;
  520.                 }
  521.                 return pfound->val;
  522.             }
  523.             d->__nextchar = NULL;
  524.             return _T('W');
  525.         }
  526.         if (temp[1] == _T(':'))
  527.         {
  528.             if (temp[2] == _T(':'))
  529.             {
  530.                 if (*d->__nextchar != _T('\0'))
  531.                 {
  532.                     d->optarg = d->__nextchar;
  533.                     d->optind++;
  534.                 }
  535.                 else
  536.                 {
  537.                     d->optarg = NULL;
  538.                 }
  539.                 d->__nextchar = NULL;
  540.             }
  541.             else
  542.             {
  543.                 if (*d->__nextchar != _T('\0'))
  544.                 {
  545.                     d->optarg = d->__nextchar;
  546.                     d->optind++;
  547.                 }
  548.                 else if (d->optind == argc)
  549.                 {
  550.                     if (print_errors)
  551.                     {
  552.                         _ftprintf(stderr
  553.                             , _T("%s: option requires an ")
  554.                             _T("argument -- '%c'\n")
  555.                             , argv[0]
  556.                             , c);
  557.                     }
  558.                     d->optopt = c;
  559.                     if (optstring[0] == _T(':'))
  560.                     {
  561.                         c = _T(':');
  562.                     }
  563.                     else
  564.                     {
  565.                         c = _T('?');
  566.                     }
  567.                 }
  568.                 else
  569.                 {
  570.                     d->optarg = argv[d->optind++];
  571.                 }
  572.                 d->__nextchar = NULL;
  573.             }
  574.         }
  575.         return c;
  576.     }
  577. }
  578. int _getopt_internal(int argc
  579.     , TCHAR* const* argv
  580.     , const TCHAR* optstring
  581.     , const struct option* longopts
  582.     , int* longind
  583.     , int long_only
  584.     , int posixly_correct)
  585. {
  586.     int result;
  587.     getopt_data.optind = optind;
  588.     getopt_data.opterr = opterr;
  589.     result = _getopt_internal_r(argc
  590.         , argv
  591.         , optstring
  592.         , longopts
  593.         , longind
  594.         , long_only
  595.         , &getopt_data
  596.         , posixly_correct);
  597.     optind = getopt_data.optind;
  598.     optarg = getopt_data.optarg;
  599.     optopt = getopt_data.optopt;
  600.     return result;
  601. }
  602. int getopt(int argc, TCHAR* const* argv, const TCHAR* optstring) _GETOPT_THROW
  603. {
  604.     return _getopt_internal(argc
  605.         , argv
  606.         , optstring
  607.         , (const struct option*)0
  608.         , (int*)0
  609.         , 0
  610.         , 0);
  611. }
  612. int getopt_long(int argc
  613.     , TCHAR* const* argv
  614.     , const TCHAR* options
  615.     , const struct option* long_options
  616.     , int* opt_index) _GETOPT_THROW
  617. {
  618.     return _getopt_internal(argc
  619.         , argv
  620.         , options
  621.         , long_options
  622.         , opt_index
  623.         , 0
  624.         , 0);
  625. }
  626. int _getopt_long_r(int argc
  627.     , TCHAR* const* argv
  628.     , const TCHAR* options
  629.     , const struct option* long_options
  630.     , int* opt_index
  631.     , struct _getopt_data* d)
  632. {
  633.     return _getopt_internal_r(argc
  634.         , argv
  635.         , options
  636.         , long_options
  637.         , opt_index
  638.         , 0
  639.         , d
  640.         , 0);
  641. }
  642. int getopt_long_only(int argc
  643.     , TCHAR* const* argv
  644.     , const TCHAR* options
  645.     , const struct option* long_options
  646.     , int* opt_index) _GETOPT_THROW
  647. {
  648.     return _getopt_internal(argc
  649.         , argv
  650.         , options
  651.         , long_options
  652.         , opt_index
  653.         , 1
  654.         , 0);
  655. }
  656. int _getopt_long_only_r(int argc
  657.     , TCHAR* const* argv
  658.     , const TCHAR* options
  659.     , const struct option* long_options
  660.     , int* opt_index
  661.     , struct _getopt_data* d)
  662. {
  663.     return _getopt_internal_r(argc
  664.         , argv
  665.         , options
  666.         , long_options
  667.         , opt_index
  668.         , 1
  669.         , d
  670.         , 0);
  671. }
  672. void getopt_reset()
  673. {
  674.     optarg = NULL;
  675.     optind = 1;
  676.     opterr = 1;
  677.     optopt = _T('?');
  678.     //
  679.     getopt_data.optind = 0;
  680.     getopt_data.opterr = 0;
  681.     getopt_data.optopt = 0;
  682.     getopt_data.optarg = NULL;
  683.     getopt_data.__initialized = 0;
  684.     getopt_data.__nextchar = NULL;
  685.     getopt_data.__ordering = 0;
  686.     getopt_data.__posixly_correct = 0;
  687.     getopt_data.__first_nonopt = 0;
  688.     getopt_data.__last_nonopt = 0;
  689. }
复制代码
做完以上步骤后,就可以进行猜测了。




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表