CircularArresterCurrentALGO.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "CircularArresterCurrentALGO.h"
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <iostream>
  4. #include <fstream>
  5. #include <string>
  6. #include <math.h>
  7. #include <cmath>
  8. #include <opencv2/imgproc.hpp>
  9. #include <opencv2/highgui.hpp>
  10. #include <opencv2/highgui/highgui.hpp>
  11. #include "opencv2/imgproc/types_c.h"
  12. #include <onnxruntime_cxx_api.h>
  13. #include <vector>
  14. #define SEG_IMAGE_SIZE 512
  15. #define LINE_HEIGH 120
  16. #define LINE_WIDTH 1600
  17. #define CIRCLE_RADIUS 250
  18. #define METER_RANGE 3.0
  19. using namespace cv;
  20. using namespace std;
  21. using namespace Ort;
  22. void CircularArresterCurrentALGO::Init()
  23. {
  24. string model_path = "models/ArresterMonitor.onnx";
  25. std::wstring widestr = std::wstring(model_path.begin(), model_path.end());
  26. sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
  27. ort_session = new Session(env, widestr.c_str(), sessionOptions);
  28. size_t numInputNodes = ort_session->GetInputCount();
  29. size_t numOutputNodes = ort_session->GetOutputCount();
  30. AllocatorWithDefaultOptions allocator;
  31. for (int i = 0; i < numInputNodes; i++)
  32. {
  33. input_names.push_back(ort_session->GetInputName(i, allocator));
  34. Ort::TypeInfo input_type_info = ort_session->GetInputTypeInfo(i);
  35. auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
  36. auto input_dims = input_tensor_info.GetShape();
  37. input_node_dims.push_back(input_dims);
  38. }
  39. for (int i = 0; i < numOutputNodes; i++)
  40. {
  41. output_names.push_back(ort_session->GetOutputName(i, allocator));
  42. Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);
  43. auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
  44. auto output_dims = output_tensor_info.GetShape();
  45. output_node_dims.push_back(output_dims);
  46. }
  47. this->inpHeight = input_node_dims[0][2];
  48. this->inpWidth = input_node_dims[0][3];
  49. this->outHeight = output_node_dims[0][2];
  50. this->outWidth = output_node_dims[0][3];
  51. }
  52. float CircularArresterCurrentALGO::detect(Mat& srcimg)
  53. {
  54. vector<float> input_image_ = { 1, 3, 512, 512 }; //1, 3, 512, 512
  55. Mat dstimg;
  56. Size resize_size(input_image_[2], input_image_[3]);
  57. resize(srcimg, dstimg, resize_size, 0, 0, cv::INTER_LINEAR);
  58. /*cv::imshow("test", dstimg);
  59. cv::waitKey(1000);*/
  60. int channels = dstimg.channels();
  61. input_image_.resize((this->inpWidth * this->inpHeight * dstimg.channels()));
  62. for (int c = 0; c < channels; c++)
  63. {
  64. for (int i = 0; i < this->inpHeight; i++)
  65. {
  66. for (int j = 0; j < this->inpWidth; j++)
  67. {
  68. float pix = dstimg.ptr<uchar>(i)[j * 3 + 2 - c];
  69. input_image_[(c * this->inpHeight * this->inpWidth + i * this->inpWidth + j)] = (pix / 255.0 - mean[c]) / stds[c];
  70. }
  71. }
  72. }
  73. array<int64_t, 4> input_shape_{ 1, 3, this->inpHeight, this->inpWidth };
  74. auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
  75. Value input_tensor_ = Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
  76. vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, &input_names[0], &input_tensor_, 1, output_names.data(), output_names.size());
  77. float *pred = ort_outputs[0].GetTensorMutableData<float>();
  78. Mat result(outHeight, outWidth, CV_32FC1, pred);
  79. result = 6 - result;
  80. result *= 255;
  81. result.convertTo(result, CV_8UC1);
  82. //namedWindow("分割", WINDOW_NORMAL);
  83. //imshow("分割", result);
  84. //waitKey(1);
  85. Mat binary;
  86. threshold(result, binary, 150, 255, THRESH_BINARY);//二值化阈值处理
  87. //形态学变换
  88. Mat Sobel_Y_thres;
  89. Mat element = cv::getStructuringElement(MORPH_RECT, Size(5, 5));
  90. morphologyEx(binary, Sobel_Y_thres, cv::MORPH_OPEN, element, Point(-1, -1), 2);
  91. //cv::imshow("test", Sobel_Y_thres);
  92. //cv::waitKey(3000);
  93. //cv::destroyWindow("test");
  94. //查找边界轮廓
  95. vector<vector<Point>> contours;
  96. vector<Vec4i> hierarchy;
  97. float pointerArea = 0;
  98. float scaleArea = 0;
  99. vector<int>numArea;
  100. findContours(Sobel_Y_thres, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
  101. for (size_t t = 0; t < contours.size(); t++)
  102. {
  103. drawContours(dstimg, contours, -1, Scalar(0, 0, 255), 2, 8);
  104. double area = contourArea(contours[t]);
  105. //计算指针和刻度关系
  106. numArea.push_back(area);
  107. float maxValue = 0;
  108. float minValue = 0;
  109. //scale
  110. maxValue = *max_element(numArea.begin(), numArea.end());
  111. scaleArea = maxValue;
  112. //pointer
  113. minValue = *min_element(numArea.begin(), numArea.end());
  114. if (numArea.size() == 1)
  115. {
  116. pointerArea = 0;
  117. }
  118. else
  119. {
  120. pointerArea = minValue;
  121. }
  122. }
  123. //计算表盘读数
  124. cout << "指针:" << pointerArea << " 刻度:" << scaleArea << endl;
  125. float result_ratio = (1.0 * pointerArea / (pointerArea + scaleArea));
  126. float resutValue = (result_ratio * METER_RANGE);
  127. if (resutValue>0.0f)
  128. {
  129. resutValue += 0.1;
  130. }
  131. cout << "result_ratio:" << result_ratio << " result_value:" << resutValue << endl;
  132. //resutValue = result_value;
  133. //return result_value;
  134. return resutValue;
  135. }