DoubleTemperatureGuageALGO.cpp 6.2 KB

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