123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #include "AtmosphericPressureALGO.h"
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <math.h>
- #include <cmath>
- #include <opencv2/imgproc.hpp>
- #include <opencv2/highgui.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include "opencv2/imgproc/types_c.h"
- #include <onnxruntime_cxx_api.h>
- #include <vector>
- #include "YunDaISASImageRecognitionService.h"
- #define SEG_IMAGE_SIZE 512
- #define LINE_HEIGH 120
- #define LINE_WIDTH 1600
- #define CIRCLE_RADIUS 250
- #define METER_RANGE 0.25
- using namespace cv;
- using namespace std;
- using namespace Ort;
- const float pi = 3.1415926536f;
- const int circle_center[] = { 256, 256 };
- void AtmosphericPressureALGO::Init()
- {
- string model_path = "models/yalibiao_models.onnx";
- std::wstring widestr = std::wstring(model_path.begin(), model_path.end());
- sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
- ort_session = new Session(env, widestr.c_str(), sessionOptions);
- size_t numInputNodes = ort_session->GetInputCount();
- size_t numOutputNodes = ort_session->GetOutputCount();
- AllocatorWithDefaultOptions allocator;
- for (int i = 0; i < numInputNodes; i++)
- {
- input_names.push_back(ort_session->GetInputName(i, allocator));
- Ort::TypeInfo input_type_info = ort_session->GetInputTypeInfo(i);
- auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
- auto input_dims = input_tensor_info.GetShape();
- input_node_dims.push_back(input_dims);
- }
- for (int i = 0; i < numOutputNodes; i++)
- {
- output_names.push_back(ort_session->GetOutputName(i, allocator));
- Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);
- auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
- auto output_dims = output_tensor_info.GetShape();
- output_node_dims.push_back(output_dims);
- }
- this->inpHeight = input_node_dims[0][2];
- this->inpWidth = input_node_dims[0][3];
- this->outHeight = output_node_dims[0][2];
- this->outWidth = output_node_dims[0][3];
- }
- bool AtmosphericPressureALGO::detect(Mat srcimg)
- {
- try
- {
- vector<float> input_image_ = { 1, 3, 512, 512 };
- Size resize_size(input_image_[2], input_image_[3]);
- //srcimg.convertTo(srcimg, CV_32FC3);
- resize(srcimg, dstimg, resize_size, 0, 0, cv::INTER_LINEAR);
- int channels = dstimg.channels();
- input_image_.resize((this->inpWidth * this->inpHeight * dstimg.channels()));
- for (int c = 0; c < channels; c++)
- {
- for (int i = 0; i < this->inpHeight; i++)
- {
- for (int j = 0; j < this->inpWidth; j++)
- {
- float pix = dstimg.ptr<uchar>(i)[j * 3 + 2 - c];
- input_image_[(c * this->inpHeight * this->inpWidth + i * this->inpWidth + j)] = (pix / 255.0 - mean[c]) / stds[c];
- }
- }
- }
- array<int64_t, 4> input_shape_{ 1, 3, this->inpHeight, this->inpWidth };
- auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
- Value input_tensor_ = Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
- // 开始推理
- vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, &input_names[0], &input_tensor_, 1, output_names.data(), output_names.size());
- float* pred = ort_outputs[0].GetTensorMutableData<float>();
- Mat result(outHeight, outWidth, CV_32FC1, pred);
- result = 6 - result;
- result *= 255;
- result.convertTo(result, CV_8UC1);
- dstimg = result;
- creat_line_image(256, 130);//圆半径 宽度
- return true;
- }
- catch (const std::exception& ex)
- {
- YunDaISASImageRecognitionService::ConsoleLog(ex.what());
- }
- return false;
- //return result;
- }
- void AtmosphericPressureALGO::creat_line_image(int Radius, int RingStride)
- {
- Mat rectangle;
- float theta;
- int rho;
- rectangle = Mat::zeros(Size(Radius * pi * 2, RingStride), CV_8UC1);
- int nl = rectangle.rows; // number of lines
- int nc = rectangle.cols * rectangle.channels(); // total number of elements per line
- for (int j = 0; j < nl; j++) {
- // get the address of row j
- uchar* data = rectangle.ptr<uchar>(j);
- for (int i = 0; i < nc; i++) {
- theta = pi * 2.0 / LINE_WIDTH * float(i + 1);
- rho = (Radius - j - 1);
- int position_y = (float)circle_center[0] + rho * (float)std::cos(theta) + 0.5;
- int position_x = (float)circle_center[1] - rho * (float)std::sin(theta) + 0.5;
- data[i] = dstimg.at<uchar>(position_y, position_x);
- }
- }
- dstimg = rectangle;
- get_meter_reader();
- }
- //像素值提取及累加
- void AtmosphericPressureALGO::get_meter_reader()
- {
- Mat histogram = Mat::zeros(Size(256, 1), CV_8UC1);
- int rows = LINE_HEIGH; //输入图像的行数
- int cols = LINE_WIDTH; //输入图像的列数
- int scale_num = 0;
- int pointer_num = 0;
- int sum_horsum = 0; //水平方向列相加和
- vector<int>num1;
- vector<int>num2;
- for (int c = 0; c < cols; c++)
- {
- int versum = 0;
- for (int r = 0; r < rows; r++)
- {
- int index = int(dstimg.at<uchar>(r, c));
- versum += index;
- }
- if (versum != 0)
- {
- //int max_sum_horsum = 0;
- sum_horsum += versum;
- //cout << "和:" << sum_horsum << endl;
- num1.push_back(sum_horsum);
- }
- if (versum == 0)
- {
- int maxValue = 0;
- for (auto v : num1)
- {
- if (maxValue < v) maxValue = v;
- }
- if (maxValue != 0)
- {
- //cout << "最大值:" << maxValue << endl;
- num2.push_back(maxValue);
- }
- sum_horsum = 0;
- vector<int>().swap(num1);
- }
- }
- //计算表盘读数
- int maxPosition = max_element(num2.begin(), num2.end()) - num2.begin();
- scale_num = num2.size();
- pointer_num = maxPosition;
- float result_ratio = (1.0 * pointer_num / scale_num);
- float result_value = (result_ratio * METER_RANGE) - 0.1;
- cout << "scale_num:" << scale_num << " pointer_num:" << pointer_num << " result_ratio:" << result_ratio << " result_value:" << result_value << endl;
- //return result_value;
- resultValue = result_value;
- }
|