CharacterDectect.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "CharacterDectect.h"
  2. using namespace std;
  3. bool CharacterDectect::Init(bool isCuda)
  4. {
  5. string model_path = "models/character-sim.onnx";
  6. try {
  7. net = cv::dnn::readNet(model_path);
  8. }
  9. catch (const std::exception& ex)
  10. {
  11. YunDaISASImageRecognitionService::ConsoleLog(ex.what());
  12. return false;
  13. }
  14. //cuda
  15. if (isCuda) {
  16. net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
  17. net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA_FP16);
  18. }
  19. //cpu
  20. else {
  21. net.setPreferableBackend(cv::dnn::DNN_BACKEND_DEFAULT);
  22. net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
  23. }
  24. return true;
  25. }
  26. IDetection::DectectResult CharacterDectect::GetStateResult(cv::Mat img, cv::Rect rec)
  27. {
  28. //resultValue.clear();
  29. std::cout << "test" << std::endl;
  30. try
  31. {
  32. cv::Mat ROI = img(rec);
  33. /*imwrite("test.png", ROI);
  34. YunDaISASImageRecognitionService::SetImage(QString::fromStdString("test.png"));*/
  35. Detect(ROI);
  36. }
  37. catch (const std::exception& ex)
  38. {
  39. YunDaISASImageRecognitionService::ConsoleLog(ex.what());
  40. }
  41. if (resultValue.m_confidence < 0.1)
  42. {
  43. resultValue = DectectResult(0.45, 0, className[1]);
  44. }
  45. return resultValue;
  46. }
  47. IDetection::DectectResult CharacterDectect::GetDigitResult(cv::Mat img, cv::Rect rec)
  48. {
  49. return resultValue;
  50. }
  51. vector<IDetection::DectectResult> CharacterDectect::GetStateResults()
  52. {
  53. return resultStateValues;
  54. }
  55. vector<IDetection::DectectResult> CharacterDectect::GetDigitResults()
  56. {
  57. return resultDigitValues;
  58. }
  59. bool CharacterDectect::Detect(cv::Mat& SrcImg) {
  60. cv::Mat blob;
  61. int col = SrcImg.cols;
  62. int row = SrcImg.rows;
  63. int maxLen = MAX(col, row);
  64. cv::Mat netInputImg = SrcImg.clone();
  65. if (maxLen > 1.2 * col || maxLen > 1.2 * row) {
  66. cv::Mat resizeImg = cv::Mat::zeros(maxLen, maxLen, CV_8UC3);
  67. SrcImg.copyTo(resizeImg(cv::Rect(0, 0, col, row)));
  68. netInputImg = resizeImg;
  69. }
  70. cv::dnn::blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(netWidth, netHeight), cv::Scalar(0, 0, 0), true, false);
  71. net.setInput(blob);
  72. std::vector<cv::Mat> netOutputImg;
  73. net.forward(netOutputImg, net.getUnconnectedOutLayersNames());
  74. std::vector<int> classIds;//结果id数组
  75. std::vector<float> confidences;//结果每个id对应置信度数组
  76. std::vector<cv::Rect> boxes;//每个id矩形框
  77. float ratio_h = (float)netInputImg.rows / netHeight;
  78. float ratio_w = (float)netInputImg.cols / netWidth;
  79. int net_width = className.size() + 5; //输出的网络宽度是类别数+5
  80. float* pdata = (float*)netOutputImg[0].data;
  81. for (int stride = 0; stride < strideSize; stride++) { //stride
  82. int grid_x = (int)(netWidth / netStride[stride]);
  83. int grid_y = (int)(netHeight / netStride[stride]);
  84. for (int anchor = 0; anchor < 3; anchor++) { //anchors
  85. const float anchor_w = netAnchors[stride][anchor * 2];
  86. const float anchor_h = netAnchors[stride][anchor * 2 + 1];
  87. for (int i = 0; i < grid_y; i++) {
  88. for (int j = 0; j < grid_x; j++) {
  89. float box_score = pdata[4]; ;//获取每一行的box框中含有某个物体的概率
  90. if (box_score >= boxThreshold) {
  91. cv::Mat scores(1, className.size(), CV_32FC1, pdata + 5);
  92. cv::Point classIdPoint;
  93. double max_class_socre;
  94. minMaxLoc(scores, 0, &max_class_socre, 0, &classIdPoint);
  95. max_class_socre = (float)max_class_socre;
  96. if (max_class_socre >= classThreshold)
  97. {
  98. //rect [x,y,w,h]
  99. float x = pdata[0]; //x
  100. float y = pdata[1]; //y
  101. float w = pdata[2]; //w
  102. float h = pdata[3]; //h
  103. int left = (x - 0.5 * w) * ratio_w;
  104. int top = (y - 0.5 * h) * ratio_h;
  105. int widthBox = int(w * ratio_w);
  106. int heightBox = int(h * ratio_h);
  107. widthBox = widthBox > col ? col : widthBox;
  108. heightBox = heightBox > row ? row : heightBox;
  109. left = left < 0 ? 0 : left;
  110. top = top < 0 ? 0 : top;
  111. if (left < 0 || left>col || top < 0 || top>row || widthBox > col || heightBox > row)
  112. {
  113. continue;
  114. }
  115. classIds.push_back(classIdPoint.x);
  116. confidences.push_back(max_class_socre * box_score);
  117. boxes.push_back(cv::Rect(left, top, widthBox, heightBox));
  118. }
  119. }
  120. pdata += net_width;//下一行
  121. }
  122. }
  123. }
  124. }
  125. //执行非最大抑制以消除具有较低置信度的冗余重叠框(NMS)
  126. vector<int> nms_result;
  127. cv::dnn::NMSBoxes(boxes, confidences, nmsScoreThreshold, nmsThreshold, nms_result);
  128. float confidenceMax = 0;
  129. int confidenceMaxId = 0;
  130. vector<pair<int, float>> classidConfidence;
  131. resultStateValues.clear();
  132. if (nms_result.size() > 0)
  133. {
  134. for (int i = 0; i < nms_result.size(); i++) {
  135. int idx = nms_result[i];
  136. if (confidences[idx] > confidenceMax)
  137. {
  138. confidenceMax = confidences[idx];
  139. resultValue = DectectResult(confidenceMax, 0, className[classIds[idx]]);
  140. }
  141. YunDaISASImageRecognitionService::ConsoleLog(QString::fromStdString(className[classIds[idx]]));
  142. auto item = std::find_if(classidConfidence.begin(), classidConfidence.end(), [idx](pair<int, float> p) { return p.first == idx; });
  143. if (item != classidConfidence.end())
  144. {
  145. if (item->second< confidences[idx])
  146. {
  147. item->second = confidences[idx];
  148. }
  149. }
  150. else {
  151. classidConfidence.push_back(pair<int, float>(idx, confidences[idx]));
  152. }
  153. }
  154. if (classidConfidence.size()>0)
  155. {
  156. for (size_t i = 0; i < classidConfidence.size(); i++)
  157. {
  158. if (classidConfidence[i].second>0.65)
  159. {
  160. resultStateValues.push_back(DectectResult(classidConfidence[i].second, 0, className[classIds[classidConfidence[i].first]]));
  161. }
  162. }
  163. }
  164. }
  165. else
  166. {
  167. resultValue = DectectResult(confidenceMax, 0, className[1]);
  168. }
  169. return true;
  170. }