#include "AngleNet.h" #include "OcrUtils.h" #include void AngleNet::setGpuIndex(int gpuIndex) { } AngleNet::~AngleNet() { delete session; inputNamesPtr.clear(); outputNamesPtr.clear(); } void AngleNet::setNumThread(int numOfThread) { numThread = numOfThread; sessionOptions.SetInterOpNumThreads(numThread); } void AngleNet::initModel(const std::string &pathStr) { //设置DCU OrtROCMProviderOptions rocm_options; rocm_options.device_id = 0; sessionOptions.AppendExecutionProvider_ROCM(rocm_options); sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_BASIC); session = new Ort::Session(env, pathStr.c_str(), sessionOptions); inputNamesPtr = getInputNames(session); outputNamesPtr = getOutputNames(session); } Angle scoreToAngle(const std::vector &outputData) { int maxIndex = 0; float maxScore = 0; for (size_t i = 0; i < outputData.size(); i++) { if (outputData[i] > maxScore) { maxScore = outputData[i]; maxIndex = i; } } return {maxIndex, maxScore}; } Angle AngleNet::getAngle(cv::Mat &src) { std::vector inputTensorValues = substractMeanNormalize(src, meanValues, normValues); std::array inputShape{1, src.channels(), src.rows, src.cols}; auto memoryInfo = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU); Ort::Value inputTensor = Ort::Value::CreateTensor(memoryInfo, inputTensorValues.data(), inputTensorValues.size(), inputShape.data(), inputShape.size()); assert(inputTensor.IsTensor()); std::vector inputNames = {inputNamesPtr.data()->get()}; std::vector outputNames = {outputNamesPtr.data()->get()}; auto outputTensor = session->Run(Ort::RunOptions{nullptr}, inputNames.data(), &inputTensor, inputNames.size(), outputNames.data(), outputNames.size()); assert(outputTensor.size() == 1 && outputTensor.front().IsTensor()); std::vector outputShape = outputTensor[0].GetTensorTypeAndShapeInfo().GetShape(); int64_t outputCount = std::accumulate(outputShape.begin(), outputShape.end(), 1, std::multiplies()); float *floatArray = outputTensor.front().GetTensorMutableData(); std::vector outputData(floatArray, floatArray + outputCount); return scoreToAngle(outputData); } std::vector AngleNet::getAngles(std::vector &partImgs, const char *path, const char *imgName, bool doAngle, bool mostAngle) { size_t size = partImgs.size(); std::vector angles(size); if (doAngle) { for (size_t i = 0; i < size; ++i) { double startAngle = getCurrentTime(); cv::Mat angleImg; cv::resize(partImgs[i], angleImg, cv::Size(dstWidth, dstHeight)); Angle angle = getAngle(angleImg); double endAngle = getCurrentTime(); angle.time = endAngle - startAngle; angles[i] = angle; //输出img if (isOutputAngleImg) { std::string angleImgFile = getDebugImgFilePath(path, imgName, i, "-angle-"); saveImg(angleImg, angleImgFile.c_str()); } } } else { for (size_t i = 0; i < size; ++i) { angles[i] = Angle{-1, 0.f}; } } //最可能的角度索引 if (doAngle && mostAngle) { auto angleIndexes = getAngleIndexes(angles); double sum = std::accumulate(angleIndexes.begin(), angleIndexes.end(), 0.0); double halfPercent = angles.size() / 2.0f; int mostAngleIndex; if (sum < halfPercent) {//all angle set to 0 mostAngleIndex = 0; } else {//all angle set to 1 mostAngleIndex = 1; } for (size_t i = 0; i < angles.size(); ++i) { Angle angle = angles[i]; angle.index = mostAngleIndex; angles.at(i) = angle; } } return angles; }