void GuiInfoAdder::addInfo(cv::Mat& cvOutputData, const int numberPeople, const unsigned long long id, const std::string& elementRenderedName, const unsigned long long frameNumber, const Array<long long>& poseIds, const Array<float>& poseKeypoints) { try { // Sanity check if (cvOutputData.empty()) error("Wrong input element (empty cvOutputData).", __LINE__, __FUNCTION__, __FILE__); // Size const auto borderMargin = intRound(fastMax(cvOutputData.cols, cvOutputData.rows) * 0.025); // Update fps updateFps(mLastId, mFps, mFpsCounter, mFpsQueue, id, mNumberGpus); // Fps or s/gpu char charArrayAux[15]; std::snprintf(charArrayAux, 15, "%4.1f fps", mFps); // Recording inverse: sec/gpu // std::snprintf(charArrayAux, 15, "%4.2f s/gpu", (mFps != 0. ? mNumberGpus/mFps : 0.)); putTextOnCvMat(cvOutputData, charArrayAux, {intRound(cvOutputData.cols - borderMargin), borderMargin}, WHITE_SCALAR, true, cvOutputData.cols); // Part to show // Allowing some buffer when changing the part to show (if >= 2 GPUs) // I.e. one GPU might return a previous part after the other GPU returns the new desired part, it looks // like a mini-bug on screen // Difference between Titan X (~110 ms) & 1050 Ti (~290ms) if (mNumberGpus == 1 || (elementRenderedName != mLastElementRenderedName && mLastElementRenderedCounter > 4)) { mLastElementRenderedName = elementRenderedName; mLastElementRenderedCounter = 0; } mLastElementRenderedCounter = fastMin(mLastElementRenderedCounter, std::numeric_limits<int>::max() - 5); mLastElementRenderedCounter++; // Add each person ID addPeopleIds(cvOutputData, poseIds, poseKeypoints, borderMargin); // OpenPose name as well as help or part to show putTextOnCvMat(cvOutputData, "OpenPose - " + (!mLastElementRenderedName.empty() ? mLastElementRenderedName : (mGuiEnabled ? "'h' for help" : "")), {borderMargin, borderMargin}, WHITE_SCALAR, false, cvOutputData.cols); // Frame number putTextOnCvMat(cvOutputData, "Frame: " + std::to_string(frameNumber), {borderMargin, (int)(cvOutputData.rows - borderMargin)}, WHITE_SCALAR, false, cvOutputData.cols); // Number people putTextOnCvMat(cvOutputData, "People: " + std::to_string(numberPeople), {(int)(cvOutputData.cols - borderMargin), (int)(cvOutputData.rows - borderMargin)}, WHITE_SCALAR, true, cvOutputData.cols); } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } }
void GuiInfoAdder::addInfo(cv::Mat& cvOutputData, const Array<float>& poseKeypoints, const unsigned long long id, const std::string& elementRenderedName) { try { // Security checks if (cvOutputData.empty()) error("Wrong input element (empty cvOutputData).", __LINE__, __FUNCTION__, __FILE__); // Update fps updateFps(mLastId, mFps, mFpsCounter, mFpsQueue, id, mNumberGpus); // Used colors const cv::Scalar white{255, 255, 255}; // Fps or s/gpu char charArrayAux[15]; std::snprintf(charArrayAux, 15, "%4.1f fps", mFps); // Recording inverse: sec/gpu // std::snprintf(charArrayAux, 15, "%4.2f s/gpu", (mFps != 0. ? mNumberGpus/mFps : 0.)); putTextOnCvMat(cvOutputData, charArrayAux, {mBorderMargin,mBorderMargin}, white, false); // Part to show // Allowing some buffer when changing the part to show (if >= 2 GPUs) // I.e. one GPU might return a previous part after the other GPU returns the new desired part, it looks like a mini-bug on screen // Difference between Titan X (~110 ms) & 1050 Ti (~290ms) if (mNumberGpus == 1 || (elementRenderedName != mLastElementRenderedName && mLastElementRenderedCounter > 4)) { mLastElementRenderedName = elementRenderedName; mLastElementRenderedCounter = 0; } mLastElementRenderedCounter = fastMin(mLastElementRenderedCounter, std::numeric_limits<int>::max() - 5); mLastElementRenderedCounter++; // Display element to display or help std::string message = (!mLastElementRenderedName.empty() ? mLastElementRenderedName : (mGuiEnabled ? "'h' for help" : "")); if (!message.empty()) putTextOnCvMat(cvOutputData, message, {intRound(mOutputSize.x - mBorderMargin), mBorderMargin}, white, true); // Frame number putTextOnCvMat(cvOutputData, "Frame " + std::to_string(id), {mBorderMargin, (int)(mOutputSize.y - mBorderMargin)}, white, false); // Number people const auto textToDisplay = std::to_string(poseKeypoints.getSize(0)) + " people"; putTextOnCvMat(cvOutputData, textToDisplay, {(int)(mOutputSize.x - mBorderMargin), (int)(mOutputSize.y - mBorderMargin)}, white, true); } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } }
void addPeopleIds(cv::Mat& cvOutputData, const Array<long long>& poseIds, const Array<float>& poseKeypoints, const int borderMargin) { try { if (!poseIds.empty()) { const auto poseKeypointsArea = poseKeypoints.getSize(1)*poseKeypoints.getSize(2); const auto isVisible = 0.05f; for (auto i = 0u ; i < poseIds.getVolume() ; i++) { if (poseIds[i] > -1) { const auto indexMain = i * poseKeypointsArea; const auto indexSecondary = i * poseKeypointsArea + poseKeypoints.getSize(2); if (poseKeypoints[indexMain+2] > isVisible || poseKeypoints[indexSecondary+2] > isVisible) { const auto xA = intRound(poseKeypoints[indexMain]); const auto yA = intRound(poseKeypoints[indexMain+1]); const auto xB = intRound(poseKeypoints[indexSecondary]); const auto yB = intRound(poseKeypoints[indexSecondary+1]); int x; int y; if (poseKeypoints[indexMain+2] > isVisible && poseKeypoints[indexSecondary+2] > isVisible) { const auto keypointRatio = intRound(0.15f * std::sqrt((xA-xB)*(xA-xB) + (yA-yB)*(yA-yB))); x = xA + 3*keypointRatio; y = yA - 3*keypointRatio; } else if (poseKeypoints[indexMain+2] > isVisible) { x = xA + intRound(0.25f*borderMargin); y = yA - intRound(0.25f*borderMargin); } else //if (poseKeypoints[indexSecondary+2] > isVisible) { x = xB + intRound(0.25f*borderMargin); y = yB - intRound(0.5f*borderMargin); } putTextOnCvMat(cvOutputData, std::to_string(poseIds[i]), {x, y}, WHITE_SCALAR, false, cvOutputData.cols); } } } } } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } }