CircularOilSinglePointALGO.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "CircularOilSinglePointALGO.h"
  2. #define SEG_IMAGE_SIZE 512
  3. #define LINE_HEIGH 120
  4. #define LINE_WIDTH 1600
  5. #define CIRCLE_RADIUS 250
  6. #define METER_RANGE 10
  7. using namespace cv;
  8. using namespace std;
  9. using namespace Ort;
  10. void CircularOilSinglePointALGO::Init(bool isCuda)
  11. {
  12. string model_path = "models/single_oil_gage.onnx";
  13. std::wstring widestr = std::wstring(model_path.begin(), model_path.end());
  14. sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
  15. ort_session = new Session(env, widestr.c_str(), sessionOptions);
  16. size_t numInputNodes = ort_session->GetInputCount();
  17. size_t numOutputNodes = ort_session->GetOutputCount();
  18. AllocatorWithDefaultOptions allocator;
  19. for (int i = 0; i < numInputNodes; i++)
  20. {
  21. input_names.push_back(ort_session->GetInputName(i, allocator));
  22. Ort::TypeInfo input_type_info = ort_session->GetInputTypeInfo(i);
  23. auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
  24. auto input_dims = input_tensor_info.GetShape();
  25. input_node_dims.push_back(input_dims);
  26. }
  27. for (int i = 0; i < numOutputNodes; i++)
  28. {
  29. output_names.push_back(ort_session->GetOutputName(i, allocator));
  30. Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);
  31. auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
  32. auto output_dims = output_tensor_info.GetShape();
  33. output_node_dims.push_back(output_dims);
  34. }
  35. this->inpHeight = input_node_dims[0][2];
  36. this->inpWidth = input_node_dims[0][3];
  37. this->outHeight = output_node_dims[0][2];
  38. this->outWidth = output_node_dims[0][3];
  39. }
  40. float CircularOilSinglePointALGO::detect(Mat& srcimg)
  41. {
  42. //cv::imshow("srcimg", srcimg);
  43. //waitKey(1);
  44. vector<float> input_image_ = { 1, 3, 512, 512 };
  45. Mat dstimg;
  46. Size resize_size(input_image_[2], input_image_[3]);
  47. resize(srcimg, dstimg, resize_size, 0, 0, cv::INTER_LINEAR);
  48. int channels = dstimg.channels();
  49. input_image_.resize((this->inpWidth * this->inpHeight * dstimg.channels()));
  50. for (int c = 0; c < channels; c++)
  51. {
  52. for (int i = 0; i < this->inpHeight; i++)
  53. {
  54. for (int j = 0; j < this->inpWidth; j++)
  55. {
  56. float pix = dstimg.ptr<uchar>(i)[j * 3 + 2 - c];
  57. input_image_[(c * this->inpHeight * this->inpWidth + i * this->inpWidth + j)] = (pix / 255.0 - mean[c]) / stds[c];
  58. }
  59. }
  60. }
  61. array<int64_t, 4> input_shape_{ 1, 3, this->inpHeight, this->inpWidth };
  62. auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
  63. Value input_tensor_ = Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
  64. // 开始推理
  65. vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, &input_names[0], &input_tensor_, 1, output_names.data(), output_names.size());
  66. float* pred = ort_outputs[0].GetTensorMutableData<float>();
  67. Mat result(outHeight, outWidth, CV_32FC1, pred);
  68. result = 4 - result;
  69. result *= 255;
  70. result.convertTo(result, CV_8UC1);
  71. //cv::imshow("imageresult", result);
  72. //cv::waitKey(1);
  73. Mat srcCopy;
  74. transpose(result, srcCopy);
  75. flip(srcCopy, srcCopy, 1); //rotate 90
  76. Mat result_line_image = creat_line_image(srcCopy, 230, 160);
  77. return get_meter_reader(result_line_image);
  78. //return result;
  79. }
  80. Mat CircularOilSinglePointALGO::creat_line_image(const Mat& circle, int Radius, int RingStride)
  81. {
  82. Mat rectangle;
  83. float theta;
  84. int rho;
  85. rectangle = Mat::zeros(Size(Radius * pi * 2, RingStride), CV_8UC1);
  86. int nl = rectangle.rows; // number of lines
  87. int nc = rectangle.cols * rectangle.channels(); // total number of elements per line
  88. for (int j = 0; j < nl; j++) {
  89. // get the address of row j
  90. uchar* data = rectangle.ptr<uchar>(j);
  91. for (int i = 0; i < nc; i++) {
  92. theta = pi * 2.0 / LINE_WIDTH * float(i + 1);
  93. rho = (Radius - j - 1);
  94. int position_y = (float)circle_center[0] + rho * (float)std::cos(theta) + 0.5;
  95. int position_x = (float)circle_center[1] - rho * (float)std::sin(theta) + 0.5;
  96. data[i] = circle.at<uchar>(position_y, position_x);
  97. }
  98. }
  99. /*cv::imshow("imagererectanglesult", rectangle);
  100. cv::waitKey(1);*/
  101. return rectangle;
  102. }
  103. //像素值提取及累加
  104. float CircularOilSinglePointALGO::get_meter_reader(const Mat& image)
  105. {
  106. Mat histogram = Mat::zeros(Size(256, 1), CV_8UC1);
  107. /*cv::imshow("image1", image);
  108. cv::waitKey(1);*/
  109. int rows = LINE_HEIGH;//120 //输入图像的行数
  110. int cols = LINE_WIDTH; //1600 //输入图像的列数
  111. int scale_num = 0;
  112. int pointer_num = 0;
  113. int sum_horsum = 0;
  114. //int rows = image.rows; //输入图像的行数
  115. //int cols = image.cols; //输入图像的列数
  116. vector<int>num1;
  117. vector<int>num2;
  118. /*cv::imshow("image", image);
  119. cv::waitKey(2000);*/
  120. for (int c = 0; c < cols; c++)
  121. {
  122. if (c < image.cols)
  123. {
  124. int versum = 0;
  125. for (int r = 0; r < rows; r++)
  126. {
  127. int index = int(image.at<uchar>(r, c));
  128. versum += index;
  129. }
  130. if (versum != 0)
  131. {
  132. sum_horsum += versum;
  133. num1.push_back(sum_horsum);
  134. }
  135. if (versum == 0)
  136. {
  137. int maxValue = 0;
  138. for (auto v : num1)
  139. {
  140. if (maxValue < v) maxValue = v;
  141. }
  142. if (maxValue != 0)
  143. {
  144. num2.push_back(maxValue);
  145. }
  146. sum_horsum = 0;
  147. vector<int>().swap(num1);
  148. }
  149. }
  150. }
  151. //计算表盘读数
  152. int maxPosition = max_element(num2.begin(), num2.end()) - num2.begin();
  153. scale_num = num2.size();
  154. pointer_num = maxPosition;
  155. float result_ratio = (1.0 * pointer_num / scale_num);
  156. float result_value = (result_ratio * METER_RANGE);
  157. if (result_value != 0)
  158. {
  159. result_value += 0.3;
  160. }
  161. cout << "scale_num:" << scale_num << " pointer_num:" << pointer_num << " result_ratio:" << result_ratio << " result_value:" << result_value << endl;
  162. //destroyAllWindows();
  163. return result_value;
  164. }