SegDetector.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. #include "SegDetector.h"
  2. #include "DnnDefine.h"
  3. #ifndef _myminmax
  4. #define _myminmax
  5. #define mymin(a,b) (a) < (b) ? (a) : (b)
  6. #define mymax(a,b) (a) > (b) ? (a) : (b)
  7. #endif
  8. CSegDetector::CSegDetector(const char* strModelFile, int iBatchSize, int iInferMode, int iDeviceIndex)
  9. {
  10. {
  11. static bool bFirst = true;
  12. if (bFirst)
  13. {
  14. DnnInfer_InitGlobalLog();
  15. bFirst = false;
  16. }
  17. }
  18. m_bInit = false;
  19. m_strModelFile = strModelFile;
  20. m_pInfer = NULL;
  21. m_iMinArea = 20;
  22. m_iMinHeight = 5;
  23. m_bEnableMask = true;
  24. m_bEnableContourArea = true;
  25. m_iBatchSize = iBatchSize;
  26. m_iInferMode = iInferMode;
  27. m_iDeviceInedx = iDeviceIndex;
  28. }
  29. CSegDetector::~CSegDetector()
  30. {
  31. UnInit();
  32. }
  33. bool CSegDetector::Init()
  34. {
  35. bool bRet = false;
  36. {
  37. InferenceParameterEx inferParam;
  38. DnnInfer_GetInferParamFormModelFile(m_strModelFile.c_str(), &inferParam);
  39. m_pInfer = DnnInfer_Init(m_strModelFile.c_str(), m_iBatchSize, m_iInferMode, m_iDeviceInedx);
  40. if (m_pInfer != NULL)
  41. {
  42. m_bInit = true;
  43. DnnInfer_GetInputInfo(m_pInfer, &m_iWidth, &m_iHeight, &m_iChannel, &m_iBatchSize, &m_iLabelNum);
  44. printf("GetInputInfo %d %d %d\n", m_iWidth, m_iHeight, m_iChannel);
  45. GpuDeviceInfo gpuDeviceInfo;
  46. DnnInfer_GetDeviceInfo(&gpuDeviceInfo);
  47. for (int i = 0; i < gpuDeviceInfo.gpu_count; i++)
  48. {
  49. std::cout << "显卡名称:" << gpuDeviceInfo.gpu_name[i] << std::endl;
  50. std::cout << "显存大小:" << gpuDeviceInfo.gpu_memory_size[i] << " MB" << std::endl;
  51. std::cout << "一个block的共享内存大小:" << gpuDeviceInfo.gpu_sharedMemPerBlock[i] << " KB" << std::endl;
  52. std::cout << "block最大线程数:" << gpuDeviceInfo.gpu_maxThreadsPerBlock[i] << std::endl;
  53. }
  54. //m_iMinArea = 20;
  55. //m_iMinHeight = 5;
  56. bRet = true;
  57. }
  58. }
  59. return bRet;
  60. }
  61. bool CSegDetector::UnInit()
  62. {
  63. if (m_bInit)
  64. {
  65. m_bInit = false;
  66. if (m_pInfer != NULL)
  67. {
  68. DnnInfer_Close(m_pInfer);
  69. }
  70. }
  71. return true;
  72. }
  73. bool CSegDetector::Execute(cv::Mat& image)
  74. {
  75. if (!m_bInit)
  76. return false;
  77. m_vecDetectResult.clear();
  78. m_iHeight = image.rows;
  79. m_iWidth = image.cols;
  80. double dFx, dFy, dXoffset, dYoffset;
  81. ProcessInput(image, m_inputDatum, dFx, dFy, dXoffset, dYoffset);
  82. std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
  83. //Infer(pObject, &input, iLabelArray, fpProbalityArray);
  84. DnnInfer_Seg_Infer(m_pInfer, &m_inputDatum, &m_outputDatum);
  85. auto elapsedSeconds = std::chrono::steady_clock::now() - startTime;
  86. printf("infer cost time %lf\n", std::chrono::duration<double, std::milli>(elapsedSeconds).count());
  87. int iMaskSize = m_iHeight * m_iWidth;
  88. cv::Mat mask(m_iHeight, m_iWidth, CV_8UC1, (uchar*)((uchar*)m_outputDatum.data));
  89. std::vector<DetectorResult> vecDetectResult;
  90. MaskToDetectResult(mask, m_iMinArea, m_iMinHeight, cv::Size(m_iWidth, m_iHeight), vecDetectResult);
  91. for (int j = 0; j < vecDetectResult.size(); j++)
  92. {
  93. DetectorResult detectorResult = vecDetectResult[j];
  94. detectorResult.left = mymax((vecDetectResult[j].left - dXoffset) / dFx, 0.0);
  95. detectorResult.top = mymax((vecDetectResult[j].top - dYoffset) / dFy, 0.0);
  96. detectorResult.width = mymin(vecDetectResult[j].width / dFx, image.cols - detectorResult.left);
  97. detectorResult.height = mymin(vecDetectResult[j].height / dFy, image.rows - detectorResult.top);
  98. if (detectorResult.width > 0 && detectorResult.height > 10)
  99. {
  100. if (m_bEnableMask)
  101. {
  102. if (!detectorResult.mask.empty())
  103. cv::resize(detectorResult.mask, detectorResult.mask, cv::Size(detectorResult.width, detectorResult.height), cv::INTER_NEAREST);
  104. }
  105. if (m_bEnableContourArea)
  106. {
  107. detectorResult.area *= dFx * dFy;
  108. }
  109. m_vecDetectResult.emplace_back(detectorResult);
  110. }
  111. }
  112. return true;
  113. }
  114. bool CSegDetector::Execute(std::vector<cv::Mat>& images)
  115. {
  116. if (!m_bInit)
  117. return false;
  118. m_vecDetectResult.clear();
  119. m_iHeight = images[0].rows;
  120. m_iWidth = images[0].cols;
  121. double dFx, dFy, dXoffset, dYoffset;
  122. ProcessInputs(images, m_inputDatum, dFx, dFy, dXoffset, dYoffset);
  123. std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
  124. //Infer(pObject, &input, iLabelArray, fpProbalityArray);
  125. DnnInfer_Seg_Infer(m_pInfer, &m_inputDatum, &m_outputDatum);
  126. for (int i = 0; i < m_outputDatum.shape.N; i++)
  127. {
  128. auto elapsedSeconds = std::chrono::steady_clock::now() - startTime;
  129. printf("infer cost time %lf\n", std::chrono::duration<double, std::milli>(elapsedSeconds).count());
  130. int iMaskSize = m_iHeight * m_iWidth;
  131. cv::Mat mask(m_iHeight, m_iWidth, CV_8UC1, (uchar*)((uchar*)m_outputDatum.data + i * iMaskSize));
  132. std::vector<DetectorResult> vecDetectResult;
  133. MaskToDetectResult(mask, m_iMinArea, m_iMinHeight, cv::Size(m_iWidth, m_iHeight), vecDetectResult);
  134. for (int j = 0; j < vecDetectResult.size(); j++)
  135. {
  136. DetectorResult detectorResult = vecDetectResult[j];
  137. detectorResult.left = mymax((vecDetectResult[j].left - dXoffset) / dFx, 0.0);
  138. detectorResult.top = mymax((vecDetectResult[j].top - dYoffset) / dFy, 0.0);
  139. detectorResult.width = mymin(vecDetectResult[j].width / dFx, m_iWidth - detectorResult.left);
  140. detectorResult.height = mymin(vecDetectResult[j].height / dFy, m_iHeight - detectorResult.top);
  141. if (detectorResult.width > 0 && detectorResult.height > 10)
  142. {
  143. if (m_bEnableMask)
  144. {
  145. if (!detectorResult.mask.empty())
  146. cv::resize(detectorResult.mask, detectorResult.mask, cv::Size(detectorResult.width, detectorResult.height), cv::INTER_NEAREST);
  147. }
  148. if (m_bEnableContourArea)
  149. {
  150. detectorResult.area *= dFx * dFy;
  151. }
  152. m_vecDetectResult.emplace_back(detectorResult);
  153. }
  154. }
  155. }
  156. return true;
  157. }
  158. bool CSegDetector::ExecuteV2(cv::Mat& image)
  159. {
  160. if (!m_bInit)
  161. return false;
  162. m_vecDetectResult.clear();
  163. m_iHeight = image.rows;
  164. m_iWidth = image.cols;
  165. double dFx, dFy, dXoffset, dYoffset;
  166. ProcessInput(image, m_inputDatum, dFx, dFy, dXoffset, dYoffset);
  167. std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
  168. //Infer(pObject, &input, iLabelArray, fpProbalityArray);
  169. DnnInfer_Seg_InferV2(m_pInfer, &m_inputDatum, &m_outputDatum, &m_outputProbDatum);
  170. auto elapsedSeconds = std::chrono::steady_clock::now() - startTime;
  171. printf("infer cost time %lf\n", std::chrono::duration<double, std::milli>(elapsedSeconds).count());
  172. int iMaskSize = m_iHeight * m_iWidth;
  173. cv::Mat mask(m_iHeight, m_iWidth, CV_8UC1, (uchar*)((uchar*)m_outputDatum.data));
  174. cv::Mat maxProbMask(m_iHeight, m_iWidth, CV_32FC1, ((float*)m_outputProbDatum.data));
  175. cv::imshow("maxProb", maxProbMask);
  176. cv::waitKey(0);
  177. std::vector<DetectorResult> vecDetectResult;
  178. //ProbToDetectResult(m_outputProbDatum, m_iMinArea, m_iMinHeight, cv::Size(m_iWidth, m_iHeight), vecDetectResult);
  179. MaskToDetectResult(mask, m_iMinArea, m_iMinHeight, cv::Size(m_iWidth, m_iHeight), vecDetectResult);
  180. for (int j = 0; j < vecDetectResult.size(); j++)
  181. {
  182. DetectorResult detectorResult = vecDetectResult[j];
  183. detectorResult.left = mymax((vecDetectResult[j].left - dXoffset) / dFx, 0.0);
  184. detectorResult.top = mymax((vecDetectResult[j].top - dYoffset) / dFy, 0.0);
  185. detectorResult.width = mymin(vecDetectResult[j].width / dFx, image.cols - detectorResult.left);
  186. detectorResult.height = mymin(vecDetectResult[j].height / dFy, image.rows - detectorResult.top);
  187. if (detectorResult.width > 0 && detectorResult.height > 10)
  188. {
  189. if (m_bEnableMask)
  190. {
  191. if (!detectorResult.mask.empty())
  192. {
  193. cv::resize(detectorResult.mask, detectorResult.mask, cv::Size(detectorResult.width, detectorResult.height), cv::INTER_NEAREST);
  194. }
  195. }
  196. if (m_bEnableContourArea)
  197. {
  198. detectorResult.area *= dFx * dFy;
  199. }
  200. m_vecDetectResult.emplace_back(detectorResult);
  201. }
  202. }
  203. return true;
  204. }
  205. bool CSegDetector::ExecuteV3(cv::Mat& image)
  206. {
  207. if (!m_bInit)
  208. return false;
  209. m_vecDetectResult.clear();
  210. m_iHeight = image.rows;
  211. m_iWidth = image.cols;
  212. double dFx, dFy, dXoffset, dYoffset;
  213. ProcessInput(image, m_inputDatum, dFx, dFy, dXoffset, dYoffset);
  214. std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
  215. //Infer(pObject, &input, iLabelArray, fpProbalityArray);
  216. SegResult segResult;
  217. memset(&segResult, 0, sizeof(segResult));
  218. DnnInfer_Seg_InferV3(m_pInfer, &m_inputDatum, &segResult);
  219. auto elapsedSeconds = std::chrono::steady_clock::now() - startTime;
  220. printf("infer cost time %lf\n", std::chrono::duration<double, std::milli>(elapsedSeconds).count());
  221. int iMaskSize = m_iHeight * m_iWidth;
  222. cv::Mat mask(segResult.inferShape.H, segResult.inferShape.W, CV_8UC1, (segResult.pLabel));
  223. cv::Mat maxProbMask(segResult.inferShape.H, segResult.inferShape.W, CV_32FC1, (segResult.pProb + 1 * segResult.inferShape.H * segResult.inferShape.W));
  224. cv::imshow("maxProb", maxProbMask);
  225. cv::waitKey(0);
  226. std::vector<DetectorResult> vecDetectResult;
  227. dFx = segResult.dScale;
  228. dFy = segResult.dScale;
  229. dXoffset = segResult.offsetX;
  230. dYoffset = segResult.offsetY;
  231. //ProbToDetectResult(m_outputProbDatum, m_iMinArea, m_iMinHeight, cv::Size(m_iWidth, m_iHeight), vecDetectResult);
  232. MaskToDetectResult(mask, m_iMinArea, m_iMinHeight, cv::Size(segResult.inferShape.W, segResult.inferShape.H), vecDetectResult);
  233. for (int j = 0; j < vecDetectResult.size(); j++)
  234. {
  235. DetectorResult detectorResult = vecDetectResult[j];
  236. detectorResult.left = mymax((vecDetectResult[j].left - dXoffset) / dFx, 0.0);
  237. detectorResult.top = mymax((vecDetectResult[j].top - dYoffset) / dFy, 0.0);
  238. detectorResult.width = mymin(vecDetectResult[j].width / dFx, image.cols - detectorResult.left);
  239. detectorResult.height = mymin(vecDetectResult[j].height / dFy, image.rows - detectorResult.top);
  240. if (detectorResult.width > 0 && detectorResult.height > 10)
  241. {
  242. if (m_bEnableMask)
  243. {
  244. if (!detectorResult.mask.empty())
  245. {
  246. cv::resize(detectorResult.mask, detectorResult.mask, cv::Size(detectorResult.width, detectorResult.height), cv::INTER_NEAREST);
  247. }
  248. }
  249. if (m_bEnableContourArea)
  250. {
  251. detectorResult.area *= dFx * dFy;
  252. }
  253. m_vecDetectResult.emplace_back(detectorResult);
  254. }
  255. }
  256. return true;
  257. }
  258. bool CSegDetector::GetResults(std::vector<DetectorResult>& vecDetectorResults)
  259. {
  260. vecDetectorResults = m_vecDetectResult;
  261. return true;
  262. }
  263. void CSegDetector::EnableMask(bool bEnableMask)
  264. {
  265. m_bEnableMask = bEnableMask;
  266. }
  267. void CSegDetector::EnableContourArea(bool bEnableContourArea)
  268. {
  269. m_bEnableContourArea = bEnableContourArea;
  270. }
  271. void CSegDetector::SetMinAreaAndHeight(int minArea, int minHeight)
  272. {
  273. m_iMinArea = minArea;
  274. m_iMinHeight = minHeight;
  275. }
  276. bool CSegDetector::ProcessInput(cv::Mat& cvInput, Datum& input, double& dFx, double& dFy, double& dXoffset, double& dYoffset)
  277. {
  278. cv::Mat resizeImage;
  279. int iModelWidth = m_iWidth;
  280. int iModelHeight = m_iHeight;
  281. float fResizeScale = 1.0;
  282. int padoffsetX = 0;
  283. int padoffsetY = 0;
  284. dFx = 1.0;
  285. dFy = 1.0;
  286. dXoffset = 0;
  287. dYoffset = 0;
  288. Shape shape(1, cvInput.channels(), cvInput.rows, cvInput.cols);
  289. input.Reshape(shape);
  290. cv::Size input_size = cvInput.size();
  291. const int channels = cvInput.channels();
  292. input.SetDataItemSize(1);
  293. uchar* datum_data = (uchar*)input.Getdata();
  294. unsigned int offsetN = shape.C * shape.H * shape.W;
  295. if (cvInput.isContinuous())
  296. {
  297. memcpy(datum_data, cvInput.data, offsetN);
  298. }
  299. return true;
  300. if (false && (cvInput.rows != iModelHeight || cvInput.cols != iModelWidth))
  301. {
  302. int iheight = cvInput.rows;
  303. int iwidth = cvInput.cols;
  304. double dHeightResizeScale = 1.0 * iModelHeight / iheight;
  305. double dWidthResizeScale = 1.0 * iModelWidth / iwidth;
  306. if (dHeightResizeScale < dWidthResizeScale)
  307. {
  308. fResizeScale = dHeightResizeScale;
  309. }
  310. else
  311. {
  312. fResizeScale = dWidthResizeScale;
  313. }
  314. cv::resize(cvInput, resizeImage, cv::Size(), fResizeScale, fResizeScale);
  315. }
  316. else
  317. {
  318. resizeImage = cvInput;
  319. }
  320. if (m_iChannel == 1)
  321. {
  322. if (resizeImage.channels() == 3)
  323. {
  324. cv::cvtColor(resizeImage, resizeImage, cv::COLOR_BGR2GRAY);
  325. }
  326. cv::Mat paddMat = cv::Mat::zeros(cv::Size(iModelWidth, iModelHeight), CV_8UC1);
  327. padoffsetX = (iModelWidth - resizeImage.cols) / 2;
  328. padoffsetY = (iModelHeight - resizeImage.rows) / 2;
  329. resizeImage.copyTo(paddMat(cv::Rect(padoffsetX, padoffsetY, resizeImage.cols, resizeImage.rows)));
  330. //cvProcessedImage = paddMat;
  331. Shape shape(1, paddMat.channels(), paddMat.rows, paddMat.cols);
  332. input.Reshape(shape);
  333. cv::Size input_size = paddMat.size();
  334. const int channels = paddMat.channels();
  335. input.SetDataItemSize(1);
  336. uchar* datum_data = (uchar*)input.Getdata();
  337. unsigned int offsetN = shape.C * shape.H * shape.W;
  338. if (paddMat.isContinuous())
  339. {
  340. memcpy(datum_data, paddMat.data, offsetN);
  341. }
  342. }
  343. else
  344. {
  345. if (resizeImage.channels() == 1)
  346. {
  347. cv::cvtColor(resizeImage, resizeImage, cv::COLOR_GRAY2BGR);
  348. }
  349. cv::Mat paddMat = cv::Mat::zeros(cv::Size(iModelWidth, iModelHeight), CV_8UC3);
  350. padoffsetX = (iModelWidth - resizeImage.cols) / 2;
  351. padoffsetY = (iModelHeight - resizeImage.rows) / 2;
  352. resizeImage.copyTo(paddMat(cv::Rect(padoffsetX, padoffsetY, resizeImage.cols, resizeImage.rows)));
  353. Shape shape(1, paddMat.channels(), paddMat.rows, paddMat.cols);
  354. input.Reshape(shape);
  355. cv::Size input_size = paddMat.size();
  356. const int channels = paddMat.channels();
  357. input.SetDataItemSize(1);
  358. uchar* datum_data = (uchar*)input.Getdata();
  359. unsigned int offsetN = shape.C * shape.H * shape.W;
  360. if (paddMat.isContinuous())
  361. {
  362. memcpy(datum_data, paddMat.data, offsetN);
  363. }
  364. }
  365. dFx = fResizeScale;
  366. dFy = fResizeScale;
  367. dXoffset = padoffsetX;
  368. dYoffset = padoffsetY;
  369. return true;
  370. }
  371. bool CSegDetector::ProcessInputs(std::vector<cv::Mat>& cvInput, Datum& input, double& dFx, double& dFy, double& dXoffset, double& dYoffset)
  372. {
  373. cv::Mat resizeImage;
  374. int iModelWidth = m_iWidth;
  375. int iModelHeight = m_iHeight;
  376. float fResizeScale = 1.0;
  377. int padoffsetX = 0;
  378. int padoffsetY = 0;
  379. dFx = 1.0;
  380. dFy = 1.0;
  381. Shape shape(cvInput.size(), cvInput[0].channels(), cvInput[0].rows, cvInput[0].cols);
  382. input.SetDataItemSize(1);
  383. input.Reshape(shape);
  384. uchar* datum_data = (uchar*)input.Getdata();
  385. for (int i = 0; i < cvInput.size(); i++)
  386. {
  387. unsigned int offsetN = shape.C * shape.H * shape.W;
  388. if (cvInput[0].isContinuous())
  389. {
  390. memcpy(datum_data + i * offsetN, cvInput[0].data, offsetN);
  391. }
  392. }
  393. return true;
  394. }
  395. bool CSegDetector::ProcessInput(cv::Mat& cvInputImage, cv::Mat& cvProcessedImage, double& dFx, double& dFy, double& dXoffset, double& dYoffset)
  396. {
  397. cv::Mat resizeImage;
  398. int iModelWidth = m_iWidth;
  399. int iModelHeight = m_iHeight;
  400. float fResizeScale = 1.0;
  401. int padoffsetX = 0;
  402. int padoffsetY = 0;
  403. if (true || cvInputImage.rows != iModelHeight || cvInputImage.cols != iModelWidth)
  404. {
  405. int iheight = cvInputImage.rows;
  406. int iwidth = cvInputImage.cols;
  407. double dHeightResizeScale = 1.0 * iModelHeight / iheight;
  408. double dWidthResizeScale = 1.0 * iModelWidth / iwidth;
  409. if (dHeightResizeScale < dWidthResizeScale)
  410. {
  411. fResizeScale = dHeightResizeScale;
  412. }
  413. else
  414. {
  415. fResizeScale = dWidthResizeScale;
  416. }
  417. cv::resize(cvInputImage, resizeImage, cv::Size(), fResizeScale, fResizeScale);
  418. }
  419. else
  420. {
  421. resizeImage = cvInputImage;
  422. }
  423. if (m_iChannel == 1)
  424. {
  425. if (resizeImage.channels() == 3)
  426. {
  427. cv::cvtColor(resizeImage, resizeImage, cv::COLOR_BGR2GRAY);
  428. }
  429. cv::Mat paddMat = cv::Mat::zeros(cv::Size(iModelWidth, iModelHeight), CV_8UC1);
  430. padoffsetX = (iModelWidth - resizeImage.cols) / 2;
  431. padoffsetY = (iModelHeight - resizeImage.rows) / 2;
  432. resizeImage.copyTo(paddMat(cv::Rect(padoffsetX, padoffsetY, resizeImage.cols, resizeImage.rows)));
  433. cvProcessedImage = paddMat;
  434. }
  435. else
  436. {
  437. cv::Mat paddMat = cv::Mat::zeros(cv::Size(iModelWidth, iModelHeight), CV_8UC3);
  438. padoffsetX = (iModelWidth - resizeImage.cols) / 2;
  439. padoffsetY = (iModelHeight - resizeImage.rows) / 2;
  440. resizeImage.copyTo(paddMat(cv::Rect(padoffsetX, padoffsetY, resizeImage.cols, resizeImage.rows)));
  441. cvProcessedImage = paddMat;
  442. }
  443. dFx = fResizeScale;
  444. dFy = fResizeScale;
  445. dXoffset = padoffsetX;
  446. dYoffset = padoffsetY;
  447. return true;
  448. }
  449. bool CSegDetector::MaskToDetectResult(const cv::Mat& mask, float min_area, float min_height,
  450. const cv::Size& image_size, std::vector<DetectorResult>& vecDetectResult) {
  451. double min_val;
  452. double max_val;
  453. cv::minMaxLoc(mask, &min_val, &max_val);
  454. int max_bbox_idx = static_cast<int>(max_val);
  455. cv::Mat resized_mask;
  456. if (mask.size() != image_size)
  457. {
  458. cv::resize(mask, resized_mask, image_size, 0, 0, cv::INTER_NEAREST);
  459. }
  460. else
  461. {
  462. resized_mask = mask.clone();
  463. }
  464. for (int i = 1; i <= max_bbox_idx; i++) {
  465. cv::Mat bbox_mask = resized_mask == i;
  466. std::vector<std::vector<cv::Point>> contours;
  467. cv::findContours(bbox_mask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
  468. if (contours.empty())
  469. continue;
  470. for (int j = 0; j < contours.size(); j++)
  471. {
  472. cv::Rect rect = cv::boundingRect(contours[j]);
  473. if (std::min(rect.size().width, rect.size().height) < min_height)
  474. continue;
  475. if (rect.size().area() < min_area)
  476. continue;
  477. DetectorResult detectResult;
  478. detectResult.left = rect.x;
  479. detectResult.top = rect.y;
  480. detectResult.width = rect.width;
  481. detectResult.height = rect.height;
  482. detectResult.label = i;
  483. detectResult.score = 1.0;
  484. if (m_bEnableContourArea)
  485. {
  486. detectResult.area = cv::contourArea(contours[j]);
  487. }
  488. else
  489. {
  490. detectResult.area = detectResult.width * detectResult.height;
  491. }
  492. //detectResult.area = cv::contourArea(contours[j]);
  493. sprintf_s(detectResult.name, "%d", detectResult.label);
  494. if (m_bEnableMask)
  495. {
  496. detectResult.hasMask = true;
  497. detectResult.mask = mask(rect).clone();
  498. }
  499. else
  500. {
  501. detectResult.hasMask = false;
  502. }
  503. vecDetectResult.emplace_back(detectResult);
  504. }
  505. }
  506. return true;
  507. }
  508. bool CSegDetector::ProbToDetectResult(Datum& probDatum, float min_area, float min_height, const cv::Size& image_size, std::vector<DetectorResult>& vecDetectResult)
  509. {
  510. int score_map_size = probDatum.shape.C * probDatum.shape.H * probDatum.shape.W;
  511. const float* score_map_data =
  512. reinterpret_cast<const float*>(probDatum.data);
  513. int num_map_pixels = probDatum.shape.H * probDatum.shape.W;
  514. for (int i = 0; i < probDatum.shape.N; ++i) {
  515. const float* current_start_ptr = score_map_data + i * score_map_size;
  516. cv::Mat ori_score_mat(probDatum.shape.C,
  517. probDatum.shape.H * probDatum.shape.W,
  518. CV_32FC1, const_cast<float*>(current_start_ptr));
  519. ori_score_mat = ori_score_mat.t();
  520. cv::Mat score_mat(probDatum.shape.H, probDatum.shape.W, CV_32FC1);
  521. cv::Mat label_mat(probDatum.shape.H, probDatum.shape.W, CV_8UC1);
  522. for (int j = 0; j < ori_score_mat.rows; ++j) {
  523. double max_value;
  524. cv::Point max_id;
  525. minMaxLoc(ori_score_mat.row(j), 0, &max_value, 0, &max_id);
  526. if (max_value > 0.5)
  527. {
  528. score_mat.at<float>(j) = max_value;
  529. label_mat.at<uchar>(j) = max_id.x;
  530. }
  531. else
  532. {
  533. score_mat.at<float>(j) = max_value;
  534. label_mat.at<uchar>(j) = 0;
  535. }
  536. }
  537. MaskToDetectResult(label_mat, min_area, min_height, image_size, vecDetectResult);
  538. }
  539. return true;
  540. }