123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #include "MeterDectect.h"
- #include "DoublePointerCountALGO.h"
- #include "AtmosphericPressureALGO.h"
- #include "CircularArresterCurrentALGO.h"
- #include "ArresterCircularZeroThreeALGO.h"
- #include "CircularOilSinglePointALGO.h"
- #include "DoubleTemperatureGuageALGO.h"
- #include "AmpereMeterALGO.h"
- #include "VoltageMeterALGO.h"
- using namespace std;
- static AtmosphericPressureALGO atmosphericPressureALGO;
- static CircularArresterCurrentALGO circularArresterCurrentALGO;
- static CircularOilSinglePointALGO circularOilSinglePointALGO;
- static DoubleTemperatureGuageALGO doubleTemperatureGuageALGO;
- static AmpereMeterALGO ampereMeterALGO;
- static VoltageMeterALGO voltageMeterALGO;
- static DoublePointerCountALGO doublePointerCountALGO;
- bool MeterDectect::Init(bool isCuda)
- {
- string model_path = "models/meter-sim.onnx";
- try {
- net = cv::dnn::readNet(model_path);
- atmosphericPressureALGO.Init();
- circularArresterCurrentALGO.Init();
- circularOilSinglePointALGO.Init(isCuda);
- doubleTemperatureGuageALGO.Init(isCuda);
- ampereMeterALGO.Init(isCuda);
- voltageMeterALGO.Init(isCuda);
- /*doublePointerCountALGO.Init(isCuda);*/
- }
- catch (const std::exception& ex)
- {
- YunDaISASImageRecognitionService::ConsoleLog(ex.what());
- return false;
- }
- //cuda
- if (isCuda) {
- net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
- net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA_FP16);
- }
- //cpu
- else {
- net.setPreferableBackend(cv::dnn::DNN_BACKEND_DEFAULT);
- net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
- }
- return true;
- return false;
- }
- IDetection::DectectResult MeterDectect::GetStateResult(cv::Mat img, cv::Rect rec)
- {
- return resultValue;
- }
- IDetection::DectectResult MeterDectect::GetDigitResult(cv::Mat img, cv::Rect rec)
- {
- //resultValue.clear();
- //std::cout << "test" << std::endl;
- //try
- //{
- // cv::Mat ROI = img(rec);
- // /*imwrite("test.png", ROI);
- // YunDaISASImageRecognitionService::SetImage(QString::fromStdString("test.png"));*/
- // Detect(ROI);
- //}
- //catch (const std::exception& ex)
- //{
- // YunDaISASImageRecognitionService::ConsoleLog(ex.what());
- //}
- //if (resultValue.m_confidence < 0.1)
- //{
- // resultValue = DectectResult(0.45, 0, "");
- //}
- return resultValue;
- }
- vector<IDetection::DectectResult> MeterDectect::GetDigitResults(cv::Mat img, cv::Rect rec)
- {
- resultValues.clear();
- try
- {
- cv::Mat ROI = img(rec);
- /*imwrite("test.png", ROI);
- YunDaISASImageRecognitionService::SetImage(QString::fromStdString("test.png"));*/
- Detect(ROI);
- if (YunDaISASImageRecognitionService::GetIsShowDectect())
- {
- cv::Mat drawROI;
- ROI.copyTo(drawROI);
- DrawPred(drawROI, output,className);
- imwrite("test.png", drawROI);
- YunDaISASImageRecognitionService::SetImage(QString::fromStdString("test.png"));
- }
- }
- catch (const std::exception& ex)
- {
- YunDaISASImageRecognitionService::ConsoleLog(ex.what());
- }
- /*if (resultValue.m_confidence < 0.1)
- {
- resultValue = DectectResult(0.45, 0, "");
- }*/
- return resultValues;
- }
- bool MeterDectect::Detect(cv::Mat& SrcImg)
- {
- cv::Mat blob;
- int col = SrcImg.cols;
- int row = SrcImg.rows;
- int maxLen = MAX(col, row);
- cv::Mat netInputImg = SrcImg.clone();
- if (maxLen > 1.2 * col || maxLen > 1.2 * row) {
- cv::Mat resizeImg = cv::Mat::zeros(maxLen, maxLen, CV_8UC3);
- SrcImg.copyTo(resizeImg(cv::Rect(0, 0, col, row)));
- netInputImg = resizeImg;
- }
- cv::dnn::blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(netWidth, netHeight), cv::Scalar(0, 0, 0), true, false);
- net.setInput(blob);
- std::vector<cv::Mat> netOutputImg;
- net.forward(netOutputImg, net.getUnconnectedOutLayersNames());
- std::vector<int> classIds;//结果id数组
- std::vector<float> confidences;//结果每个id对应置信度数组
- std::vector<cv::Rect> boxes;//每个id矩形框
- float ratio_h = (float)netInputImg.rows / netHeight;
- float ratio_w = (float)netInputImg.cols / netWidth;
- int net_width = className.size() + 5; //输出的网络宽度是类别数+5
- float* pdata = (float*)netOutputImg[0].data;
- for (int stride = 0; stride < strideSize; stride++) { //stride
- int grid_x = (int)(netWidth / netStride[stride]);
- int grid_y = (int)(netHeight / netStride[stride]);
- for (int anchor = 0; anchor < 3; anchor++) { //anchors
- const float anchor_w = netAnchors[stride][anchor * 2];
- const float anchor_h = netAnchors[stride][anchor * 2 + 1];
- for (int i = 0; i < grid_y; i++) {
- for (int j = 0; j < grid_x; j++) {
- float box_score = pdata[4]; ;//获取每一行的box框中含有某个物体的概率
- if (box_score >= boxThreshold) {
- cv::Mat scores(1, className.size(), CV_32FC1, pdata + 5);
- cv::Point classIdPoint;
- double max_class_socre;
- minMaxLoc(scores, 0, &max_class_socre, 0, &classIdPoint);
- max_class_socre = (float)max_class_socre;
- if (max_class_socre >= classThreshold)
- {
- //rect [x,y,w,h]
- float x = pdata[0]; //x
- float y = pdata[1]; //y
- float w = pdata[2]; //w
- float h = pdata[3]; //h
- int left = (x - 0.5 * w) * ratio_w;
- int top = (y - 0.5 * h) * ratio_h;
- left = left < 0 ? 0 : left;
- top = top < 0 ? 0 : top;
- int widthBox = int(w * ratio_w);
- int heightBox = int(h * ratio_h);
- widthBox = widthBox > col ? col : widthBox;
- heightBox = heightBox > row ? row : heightBox;
- if (left < 0|| left>col|| top < 0|| top>row|| widthBox > col|| heightBox > row
- || left+ widthBox> col|| top+ heightBox> row
- )
- {
- continue;
- }
- classIds.push_back(classIdPoint.x);
- confidences.push_back(max_class_socre * box_score);
- //YunDaISASImageRecognitionService::ConsoleLog(QString("%1,%2,%3,%4").arg(left).arg(top).arg(widthBox).arg(heightBox));
- boxes.push_back(cv::Rect(left, top, widthBox, heightBox));
- }
- }
- pdata += net_width;//下一行
- }
- }
- }
- }
- //执行非最大抑制以消除具有较低置信度的冗余重叠框(NMS)
- vector<int> nms_result;
- cv::dnn::NMSBoxes(boxes, confidences, nmsScoreThreshold, nmsThreshold, nms_result);
- float confidenceMax = -1;
- int confidenceMaxId = 0;
- output.clear();
- if (nms_result.size() > 0)
- {
- for (int i = 0; i < nms_result.size()&&i<3; i++)
- {
- int idx = nms_result[i];
- Output result(classIds[idx], confidences[idx], boxes[idx]);
- /*int figure = 0;
- result.id = classIds[idx];
- result.confidence = confidences[idx];
- result.box = boxes[idx];*/
- output.push_back(result);
- if (className[classIds[idx]] == "rect_arrester_current")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- auto resValue = circularArresterCurrentALGO.detect(SrcImg);
- tempResultValue.m_dValue = resValue;
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "atmospheric_pressure")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- //auto resState = atmosphericPressureALGO.detect(SrcImg(boxes[idx]));
- auto resState = atmosphericPressureALGO.detect(SrcImg);
- tempResultValue.m_dValue = atmosphericPressureALGO.resultValue;
- tempResultValue.m_sValue = "atmospheric_pressure";
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "digital_gear")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "circular_arrester_current") //0-3mA避雷器电流
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- ArresterCircularZeroThreeALGO* algo = new ArresterCircularZeroThreeALGO;
- auto resNum = algo->GetResult(SrcImg(boxes[idx]), false);
- tempResultValue.m_dValue = resNum;
- delete algo;
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "ampere_meter")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- tempResultValue.m_dValue = ampereMeterALGO.detect(SrcImg);
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "voltage_meter")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- tempResultValue.m_dValue = voltageMeterALGO.detect(SrcImg);
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "double_pointer_count")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- DoublePointerCountALGO* doublePointerCountALGO = new DoublePointerCountALGO();
- int resCount = doublePointerCountALGO->GetResult(SrcImg(boxes[idx]), false);
- tempResultValue.m_dValue = resCount;
- delete doublePointerCountALGO;
- resultValues.push_back(tempResultValue);
- }
- /*else if (className[classIds[idx]] == "double_pointer_count")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- tempResultValue.m_dValue = doublePointerCountALGO.detect(SrcImg);
- resultValues.push_back(tempResultValue);
- }*/
- else if (className[classIds[idx]] == "transformers_oil_surface_thermometer")
- {
- auto tempResultValueMin = DectectResult(confidences[idx], 60, className[classIds[idx]] + "_Min");
- auto tempResultValueMax = DectectResult(confidences[idx], 80, className[classIds[idx]] + "_Max");
- auto min_max = doubleTemperatureGuageALGO.detect(SrcImg, 150);//150表示量程
- tempResultValueMin.m_dValue = min_max.first;
- tempResultValueMax.m_dValue = min_max.second;
- resultValues.push_back(tempResultValueMin);
- resultValues.push_back(tempResultValueMax);
- }
- else if (className[classIds[idx]] == "round_single_point_oil_level")
- {
- auto tempResultValue = DectectResult(confidences[idx], 0, className[classIds[idx]]);
- tempResultValue.m_dValue = circularOilSinglePointALGO.detect(SrcImg);
- resultValues.push_back(tempResultValue);
- }
- else if (className[classIds[idx]] == "oil_thermometer")//油位温控
- {
- auto tempResultValueMin = DectectResult(confidences[idx], 60, className[classIds[idx]] + "_Min");
- auto tempResultValueMax = DectectResult(confidences[idx], 80, className[classIds[idx]] + "_Max");
- auto min_max = doubleTemperatureGuageALGO.detect(SrcImg,120);//120表示量程
- tempResultValueMin.m_dValue = min_max.first;
- tempResultValueMax.m_dValue = min_max.second;
- resultValues.push_back(tempResultValueMin);
- resultValues.push_back(tempResultValueMax);
- }
- YunDaISASImageRecognitionService::ConsoleLog(QString::fromStdString(className[classIds[idx]]));
- }
- }
- else {
- resultValue = DectectResult(confidenceMax, 0.01, "");
- }
- return false;
- }
|