25 #include <boost/algorithm/string.hpp>
26 #include <boost/make_shared.hpp>
35 #include <VisionX/interface/components/OpenPoseEstimationInterface.h>
36 #include <VisionX/interface/components/RGBDImageProvider.h>
41 #include <Image/IplImageAdaptor.h>
42 #include <Image/PrimitivesDrawer.h>
43 #include <openpose/pose/poseParameters.hpp>
44 #include <openpose/pose/poseParametersRender.hpp>
48 #include <SimoxUtility/json/json.hpp>
62 positiveIntRound(
const T a)
78 providerName = getProperty<std::string>(
"ImageProviderName").getValue();
81 offeringTopic(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
83 radius = getProperty<int>(
"DepthMedianRadius").getValue();
84 useDistortionParameters = getProperty<bool>(
"UseDistortionParameters").getValue();
85 layerName =
"OpenPoseEstimation";
86 renderThreshold = getProperty<float>(
"OP_render_threshold").getValue();
88 cameraNodeName = getProperty<std::string>(
"CameraNodeName").getValue();
89 minimalValidKeypoints = getProperty<int>(
"MinimalAmountKeypoints").getValue();
90 reportOnlyNearestPerson = getProperty<bool>(
"ReportOnlyNearestPerson").getValue();
93 std::vector<Polygon2D::Point> points;
94 std::vector<std::string> pointStrings;
95 std::string
input = getProperty<std::string>(
"WorkspacePolygon").getValue();
97 for (
auto s : pointStrings)
100 std::vector<std::string> workSpacePolygonPoint;
101 boost::split(workSpacePolygonPoint,
s, boost::is_any_of(
","));
104 point.
x = std::strtof(workSpacePolygonPoint.at(0).c_str(),
nullptr);
105 point.
y = std::strtof(workSpacePolygonPoint.at(1).c_str(),
nullptr);
106 points.push_back(point);
110 mode = getProperty<OpenPoseEstimationMode>(
"Mode").getValue();
114 poseModel = op::flagsToPoseModel(
"MPI");
116 << getProperty<std::string>(
"OP_model_pose").getValue()
117 <<
"\" to \"MPI\" because the OpenPoseEstiamtionMode is set to \"FromTopic\".";
120 std::string
s = getProperty<std::string>(
"Topic_Dimensions").getValue();
128 poseModel = op::flagsToPoseModel(getProperty<std::string>(
"OP_model_pose").getValue());
131 timeoutCounter2d = 0;
132 readErrorCounter2d = 0;
142 numImages =
static_cast<unsigned int>(imageProviderInfo.
numberImages);
143 if (numImages < 1 || numImages > 2)
158 imageBuffer =
new CByteImage*[numImages];
159 for (
unsigned int i = 0; i < numImages; i++)
165 ::ImageProcessor::Zero(maskedrgbImageBuffer);
167 ::ImageProcessor::Zero(depthImageBuffer);
168 openPoseResultImage =
new CByteImage*[1];
173 offeringTopic(getProperty<std::string>(
"OpenPoseEstimation2DTopicName").getValue());
174 listener2DPrx = getTopic<OpenPose2DListenerPrx>(
175 getProperty<std::string>(
"OpenPoseEstimation2DTopicName").getValue());
176 offeringTopic(getProperty<std::string>(
"OpenPoseEstimation3DTopicName").getValue());
177 listener3DPrx = getTopic<OpenPose3DListenerPrx>(
178 getProperty<std::string>(
"OpenPoseEstimation3DTopicName").getValue());
181 stereoCalibration =
nullptr;
182 calibration =
nullptr;
184 ARMARX_VERBOSE <<
"Trying to get StereoCalibrationInterface proxy: "
186 imageProviderInfo.
proxy);
187 visionx::StereoCalibrationInterfacePrx calib =
188 visionx::StereoCalibrationInterfacePrx::checkedCast(imageProviderInfo.
proxy);
192 <<
"Image provider does not provide a stereo calibration - 3D will not work - "
193 << imageProviderInfo.
proxy->ice_ids();
200 calibration = stereoCalibration->GetLeftCalibration();
205 debugDrawerTopic = getTopic<armarx::DebugDrawerInterfacePrx>(
206 getProperty<std::string>(
"DebugDrawerTopicName").getValue());
207 debugDrawerTopic->clearLayer(layerName);
210 robotStateInterface = getProxy<RobotStateComponentInterfacePrx>(
211 getProperty<std::string>(
"RobotStateComponentName").getValue(),
false,
"",
false);
212 if (robotStateInterface)
219 ARMARX_ERROR <<
"RobotStateCompontent is not avaiable, 3D-Estimation will be deactivated!!";
227 if (getProperty<bool>(
"ActivateOnStartup").getValue())
231 task2DKeypoints->start();
247 task2DKeypoints->stop();
250 delete rgbImageBuffer;
251 delete maskedrgbImageBuffer;
252 delete depthImageBuffer;
253 delete[] imageBuffer;
254 delete[] openPoseResultImage;
255 delete stereoCalibration;
257 imageKeypointBuffer.reset();
274 <<
" (#timeout " << timeoutCounter2d <<
", #read error "
275 << readErrorCounter2d <<
", #success " << sucessCounter2d <<
")";
279 if (
static_cast<unsigned int>(
getImages(providerName, imageBuffer, imageMetaInfo)) !=
282 ++readErrorCounter2d;
284 <<
" (#timeout " << timeoutCounter2d <<
", #read error "
285 << readErrorCounter2d <<
", #success " << sucessCounter2d <<
")";
293 imageKeypointBuffer->addRGBImage(imageBuffer[0], imageMetaInfo->timeProvided);
294 if (imageKeypointBuffer->addDepthImage(imageBuffer[1],
295 imageMetaInfo->timeProvided))
297 timeProvidedImage = imageMetaInfo->timeProvided;
304 std::unique_lock lock_rgb(rgbImageBufferMutex);
305 ::ImageProcessor::CopyImage(imageBuffer[0], rgbImageBuffer);
311 std::unique_lock lock_depth(depthImageBufferMutex);
312 ::ImageProcessor::CopyImage(imageBuffer[1], depthImageBuffer);
315 timeProvidedImage = imageMetaInfo->timeProvided;
328 OpenPoseEstimation::run()
333 setupOpenPoseEnvironment();
336 while (running2D && task2DKeypoints->isRunning())
344 imageUpdated =
false;
356 if (running3D && localRobot && numImages > 1)
360 localRobot, robotStateInterface, timeProvidedImage);
378 std::unique_lock lock(keypointManagerMutex);
379 std::vector<KeypointObjectPtr>::iterator iter = keypointManager->getData().begin();
380 while (iter != keypointManager->getData().end())
386 iter = keypointManager->getData().erase(iter);
396 if (reportOnlyNearestPerson)
405 << keypointManager->getData().size() <<
" objects";
406 listener2DPrx->report2DKeypoints(keypointManager->toIce2D(), timeProvidedImage);
407 listener2DPrx->report2DKeypointsNormalized(
408 keypointManager->toIce2D_normalized(imageProviderInfo.
imageFormat.dimension.width,
412 << keypointManager->getData().size() <<
" objects";
413 listener3DPrx->report3DKeypoints(keypointManager->toIce3D(localRobot),
419 << keypointManager->getData().size() <<
" objects";
420 listener2DPrx->report2DKeypoints(keypointManager->toIce2D(), timeProvidedImage);
421 listener2DPrx->report2DKeypointsNormalized(
422 keypointManager->toIce2D_normalized(imageProviderInfo.
imageFormat.dimension.width,
433 OpenPoseEstimation::setupOpenPoseEnvironment()
438 const op::Point<int> netInputSize =
439 op::flagsToPoint(getProperty<std::string>(
"OP_net_resolution").
getValue(),
"-1x368");
440 const op::Point<int> outputSize =
441 op::flagsToPoint(getProperty<std::string>(
"OP_output_resolution").
getValue(),
"-1x-1");
442 int scaleNumber = getProperty<int>(
"OP_scale_number").getValue();
443 double scaleGap = getProperty<double>(
"OP_scale_gap").getValue();
444 scaleAndSizeExtractor = std::make_shared<op::ScaleAndSizeExtractor>(
445 netInputSize, outputSize, scaleNumber, scaleGap);
447 cvMatToOpInput = std::make_shared<op::CvMatToOpInput>(poseModel);
448 cvMatToOpOutput.reset(
new op::CvMatToOpOutput());
449 opOutputToCvMat.reset(
new op::OpOutputToCvMat());
451 std::string modelFolder;
453 modelFolder = getProperty<std::string>(
"OP_model_folder").getValue();
455 modelFolder, modelFolder, {
"/usr/share/OpenPose/", OPENPOSE_MODELS});
461 if (!modelFolder.empty() && *modelFolder.rbegin() !=
'/')
465 ARMARX_INFO <<
"Found model path at: " << modelFolder;
466 int numGpuStart = getProperty<int>(
"OP_num_gpu_start").getValue();
468 std::make_shared<op::PoseExtractorCaffe>(poseModel, modelFolder, numGpuStart);
469 poseExtractorCaffe->initializationOnThread();
475 OpenPoseEstimation::getPoseKeypoints(CByteImage* imageBuffer)
478 IplImage* iplImage = IplImageAdaptor::Adapt(imageBuffer);
479 cv::Mat inputImage = cv::cvarrToMat(iplImage);
480 const op::Point<int> imageSize{inputImage.cols, inputImage.rows};
483 std::vector<double> scaleInputToNetInputs;
484 std::vector<op::Point<int>> netInputSizes;
485 double scaleInputToOutput;
486 op::Point<int> outputResolution;
487 std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution) =
488 scaleAndSizeExtractor->extract(imageSize);
491 const auto netInputArray =
492 cvMatToOpInput->createArray(inputImage, scaleInputToNetInputs, netInputSizes);
495 poseExtractorCaffe->forwardPass(netInputArray, imageSize, scaleInputToNetInputs);
496 const PoseKeypoints poseKeypoints = poseExtractorCaffe->getPoseKeypoints();
498 return poseKeypoints;
503 const CByteImage& maskedInputImage,
505 CByteImage& resultImage,
506 op::PoseModel poseModel,
507 float renderThreshold,
508 int brightnessIncrease)
510 IdNameMap m1 = keypointManager->getIdNameMap();
511 IdNameMap poseBodyPartMapping = getPoseBodyPartMapping(poseModel);
513 std::equal(m1.begin(), m1.end(), poseBodyPartMapping.begin()))
514 <<
"The idNameMap used in the keypointManager must be equal to the poseBodyPartMapping "
515 "defined by the given poseModel.";
518 const int objects = keypointManager->getData().size();
519 const int numberKeypoints = m1.size();
522 int objectNumber = 0;
525 for (
int i = 0; i < numberKeypoints; i++)
527 const int index = (objectNumber * numberKeypoints + i) * opKeypoints.getSize(2);
528 KeypointPtr p = obj->getNode(
static_cast<unsigned int>(i));
531 opKeypoints[
index] = p->get2D()._x;
532 opKeypoints[
index + 1] = p->get2D()._y;
533 opKeypoints[
index + 2] = p->getConfidence();
537 opKeypoints[
index] = 0.0f;
538 opKeypoints[
index + 1] = 0.0f;
539 opKeypoints[
index + 2] = 0.0f;
544 std::cout << opKeypoints.toString() << std::endl;
558 const CByteImage& maskedInputImage,
559 int brightnessIncrease,
560 const CByteImage& inputImage)
562 Ice::Byte mask[3] = {0, 255, 0};
563 auto pixelCount = inputImage.width * inputImage.height;
566 CByteImage imageMask(maskedInputImage.width, maskedInputImage.height, CByteImage::eGrayScale);
567 CByteImage smoothedImageMask(&imageMask);
568 ::ImageProcessor::Zero(&imageMask);
569 if (brightnessIncrease > 0)
571 for (
int i = 0; i < pixelCount; i += 1)
573 if (maskedInputImage.pixels[i * 3] == mask[0] &&
574 maskedInputImage.pixels[i * 3 + 1] == mask[1] &&
575 maskedInputImage.pixels[i * 3 + 2] == mask[2])
577 imageMask.pixels[i] = 255;
580 ::ImageProcessor::GaussianSmooth5x5(&imageMask, &smoothedImageMask);
583 for (
int i = 0; i < pixelCount; i += 1)
585 if (brightnessIncrease > 0)
587 float perc =
static_cast<float>(smoothedImageMask.pixels[i]) / 255.f;
588 int effectiveBrightnessIncrease = brightnessIncrease * perc;
589 resultImage.pixels[i * 3] =
590 std::min<int>(resultImage.pixels[i * 3] + effectiveBrightnessIncrease, 255);
591 resultImage.pixels[i * 3 + 1] =
592 std::min<int>(resultImage.pixels[i * 3 + 1] + effectiveBrightnessIncrease, 255);
593 resultImage.pixels[i * 3 + 2] =
594 std::min<int>(resultImage.pixels[i * 3 + 2] + effectiveBrightnessIncrease, 255);
597 else if (brightnessIncrease < 0)
599 if (maskedInputImage.pixels[i * 3] == mask[0] &&
600 maskedInputImage.pixels[i * 3 + 1] == mask[1] &&
601 maskedInputImage.pixels[i * 3 + 2] == mask[2])
603 resultImage.pixels[i * 3] = maskedInputImage.pixels[i * 3];
604 resultImage.pixels[i * 3 + 1] = maskedInputImage.pixels[i * 3 + 1];
605 resultImage.pixels[i * 3 + 2] = maskedInputImage.pixels[i * 3 + 2];
613 const CByteImage& maskedInputImage,
615 CByteImage& resultImage,
616 op::PoseModel poseModel,
617 float renderThreshold,
618 int brightnessIncrease)
622 ::ImageProcessor::CopyImage(&inputImage, &resultImage);
626 if (keypoints.getSize().empty())
631 const std::vector<unsigned int>& posePartPairs = op::getPoseBodyPartPairsRender(poseModel);
634 std::vector<float> keypointColors = op::getPoseColors(poseModel);
636 const auto thicknessCircleRatio = 1.f / 75.f;
637 const auto thicknessLineRatioWRTCircle = 0.75f;
638 const auto area = inputImage.width * inputImage.height;
639 const int numberKeypoints = keypoints.getSize(1);
641 for (
int person = 0; person < keypoints.getSize(0); person++)
643 const auto personRectangle = op::getKeypointsRectangle(keypoints, person, 0.1f);
644 if (personRectangle.area() > 0)
647 const auto ratioAreas = op::fastMin(
649 op::fastMax(personRectangle.width /
static_cast<float>(inputImage.width),
650 personRectangle.height /
static_cast<float>(inputImage.height)));
651 const auto thicknessRatio =
652 op::fastMax(positiveIntRound<float>(
static_cast<float>(
std::sqrt(area)) *
653 thicknessCircleRatio * ratioAreas),
656 const auto thicknessCircle = op::fastMax(1, (ratioAreas > 0.05f ? thicknessRatio : -1));
657 const auto thicknessLine =
658 op::fastMax(1, positiveIntRound(thicknessRatio * thicknessLineRatioWRTCircle));
659 const auto radius = thicknessRatio / 2;
662 for (
unsigned int i = 0; i < posePartPairs.size(); i = i + 2)
664 const int index1 = (person * numberKeypoints +
static_cast<int>(posePartPairs[i])) *
665 keypoints.getSize(2);
667 (person * numberKeypoints +
static_cast<int>(posePartPairs[i + 1])) *
668 keypoints.getSize(2);
670 float x1 = keypoints[index1 + 0];
671 float y1 = keypoints[index1 + 1];
672 float x2 = keypoints[index2 + 0];
673 float y2 = keypoints[index2 + 1];
675 if (!(x1 == 0.0f && y1 == 0.0f) && !(x2 == 0.0f && y2 == 0.0f))
677 if (keypoints[index1 + 2] > renderThreshold &&
678 keypoints[index2 + 2] > renderThreshold)
680 unsigned int colorIndex = posePartPairs[i + 1] * 3;
681 ::PrimitivesDrawer::DrawLine(
685 static_cast<int>(keypointColors[colorIndex + 2]),
686 static_cast<int>(keypointColors[colorIndex + 1]),
687 static_cast<int>(keypointColors[colorIndex + 0]),
694 for (
int i = 0; i < numberKeypoints; i++)
696 const int index = (person * numberKeypoints + i) * keypoints.getSize(2);
697 float x = keypoints[
index + 0];
698 float y = keypoints[
index + 1];
700 if (!(x == 0.0f && y == 0.0f) && keypoints[
index + 2] > renderThreshold)
702 unsigned int colorIndex =
static_cast<unsigned int>(i * 3);
704 ::PrimitivesDrawer::DrawCircle(&resultImage,
708 static_cast<int>(keypointColors[colorIndex + 2]),
709 static_cast<int>(keypointColors[colorIndex + 1]),
710 static_cast<int>(keypointColors[colorIndex + 0]),
730 task2DKeypoints->start();
741 task2DKeypoints->stop(
true);
755 ARMARX_INFO <<
"Starting OpenposeEstimation -- 3D";
767 ARMARX_INFO <<
"Stopping OpenposeEstimation -- 3D";
781 std::unique_lock lock(depthImageBufferMutex);
787 int pixelCount = depthImageBuffer->width * depthImageBuffer->height;
788 int depthThresholdmm = maxDepth;
789 CByteImage maskImage(depthImageBuffer->width, depthImageBuffer->height, CByteImage::eGrayScale);
790 for (
int i = 0; i < pixelCount; i += 1)
792 int z_value = depthImageBuffer->pixels[i * 3 + 0] +
793 (depthImageBuffer->pixels[i * 3 + 1] << 8) +
794 (depthImageBuffer->pixels[i * 3 + 2] << 16);
795 maskImage.pixels[i] = z_value > depthThresholdmm || z_value == 0 ? 0 : 255;
797 ::ImageProcessor::Erode(&maskImage, &maskImage, 5);
798 ::ImageProcessor::Dilate(&maskImage, &maskImage, 20);
799 for (
int i = 0; i < pixelCount; i += 1)
801 if (maskImage.pixels[i] == 0)
803 image.pixels[i * 3] = 0;
804 image.pixels[i * 3 + 1] = 255;
805 image.pixels[i * 3 + 2] = 0;
813 int windowSize)
const
815 if (point.x < 0 || point.y < 0 || point.x >= image.width || point.y >= image.height)
816 return DrawColor24Bit{0, 0, 0};
817 int divisor = 256 / 3;
818 typedef std::tuple<Ice::Byte, Ice::Byte, Ice::Byte> RGBTuple;
819 std::map<RGBTuple, int> histogram;
820 int halfWindowSize =
static_cast<int>(windowSize * 0.5);
821 int left = std::max<int>(0,
static_cast<int>(point.x) - halfWindowSize);
822 int top = std::max<int>(0,
static_cast<int>(point.y) - halfWindowSize);
823 int right = std::min<int>(image.width,
static_cast<int>(point.x) + halfWindowSize);
824 int bottom = std::min<int>(image.height,
static_cast<int>(point.y) + halfWindowSize);
826 for (
int x = left; x < right; x++)
828 for (
int y = top; y < bottom; y++)
830 int pixelPos = (y * image.width + x) * 3;
831 auto tuple = std::make_tuple<Ice::Byte, Ice::Byte, Ice::Byte>(
832 static_cast<Ice::Byte
>(image.pixels[pixelPos] / divisor),
833 static_cast<Ice::Byte
>(image.pixels[pixelPos + 1] / divisor),
834 static_cast<Ice::Byte
>(image.pixels[pixelPos + 2] / divisor));
835 if (histogram.count(tuple))
837 histogram.at(tuple)++;
841 histogram[tuple] = 1;
846 float maxHistogramValue = 0;
847 RGBTuple dominantColor;
848 for (
auto& pair : histogram)
850 if (pair.second > maxHistogramValue)
852 dominantColor = pair.first;
853 maxHistogramValue = pair.second;
856 auto rgb = DrawColor24Bit{
static_cast<Ice::Byte
>(std::get<0>(dominantColor) * divisor),
857 static_cast<Ice::Byte
>(std::get<1>(dominantColor) * divisor),
858 static_cast<Ice::Byte
>(std::get<2>(dominantColor) * divisor)};
865 using json = nlohmann::json;
867 json jsonView = json::parse(text.message);
870 long timestamp = jsonView[
"timestamp"].get<
long>();
871 json jsonValues = jsonView[
"values"];
874 IdNameMap poseBodyPartMapping = getPoseBodyPartMapping(poseModel);
878 float adjustingWidth =
static_cast<float>(imageProviderInfo.
imageFormat.dimension.width) /
879 static_cast<float>(this->incomingKeypointDimensions.width);
880 float adjustingHeight =
static_cast<float>(imageProviderInfo.
imageFormat.dimension.height) /
881 static_cast<float>(this->incomingKeypointDimensions.height);
883 for (json::iterator it = jsonValues.begin(); it != jsonValues.end(); ++it)
885 std::string jsonLabel = it.key();
888 unsigned int id = pair.first;
889 std::string name = pair.second;
891 json jsonPosition = it.value();
892 json jsonPoint = jsonPosition[
"position"];
893 float x = jsonPoint[
"y"];
894 float y = jsonPoint[
"x"];
898 y *= adjustingHeight;
900 if (x > 0.0f && y > 0.0f)
908 object->insertNode(keypoint);
911 manager->getData().push_back(
object);
914 if (imageKeypointBuffer->addKeypoints(manager, timestamp))
916 timeProvidedImage = timestamp;
923 const CByteImage& rgbImage)
const
925 IdNameMap poseBodyPartMapping = getPoseBodyPartMapping(poseModel);
928 if (keypoints.getSize().empty())
930 debugDrawerTopic->removeLayer(
937 int entities = keypoints.getSize().at(0);
938 int points = keypoints.getSize().at(1);
941 for (
int i = 0; i < entities; i++)
944 for (
int id = 0;
id < points;
id++)
946 float x = keypoints.at({i, id, 0});
947 float y = keypoints.at({i, id, 1});
948 if (x == 0.0f && y == 0.0f)
954 std::make_shared<Keypoint>(x,
956 static_cast<unsigned int>(
id),
957 poseBodyPartMapping.at(
static_cast<unsigned int>(
id)),
958 static_cast<float>(keypoints.at({i, id, 2})));
960 keypoint->setDominantColor(
962 object->insertNode(keypoint);
965 if (
static_cast<int>(object->size()) >= minimalValidKeypoints)
967 manager->getData().push_back(
object);
982 for (
unsigned int i = 0; i < getPoseBodyPartMapping(poseModel).size(); i++)
985 if (point && point->is3DSet())
988 if (!workspacePolygon.
isInside(pos))
991 object->removeNode(i);
1000 this->keypointManager->filterToNearestN(1);
1006 std::unique_lock lock(keypointManagerMutex);
1010 std::unique_lock lock_rgb(rgbImageBufferMutex);
1012 ::ImageProcessor::CopyImage(rgbImageBuffer, maskedrgbImageBuffer);
1022 std::unique_lock lock(resultImageBufferMutex);
1025 *maskedrgbImageBuffer,
1027 *openPoseResultImage[0],
1030 getProperty<int>(
"MaskBrightnessIncrease").getValue());
1036 std::unique_lock lock_rgb(rgbImageBufferMutex);
1037 std::unique_lock lock_depth(depthImageBufferMutex);
1042 keypointManager->matchWith(m2);
1046 std::unique_lock lock(resultImageBufferMutex);
1051 *openPoseResultImage[0],
1054 getProperty<int>(
"MaskBrightnessIncrease").getValue());
1065 imageKeypointBuffer->getTripleAtTimestamp(timeProvidedImage,
true);
1066 std::unique_lock lock_rgb(rgbImageBufferMutex);
1067 ::ImageProcessor::CopyImage(imageKeypointTriple->rgbImage, rgbImageBuffer);
1068 std::unique_lock lock_depth(depthImageBufferMutex);
1069 ::ImageProcessor::CopyImage(imageKeypointTriple->depthImage, depthImageBuffer);
1070 keypointManager = imageKeypointTriple->keypoints;
1074 std::unique_lock lock(resultImageBufferMutex);
1079 *openPoseResultImage[0],
1082 getProperty<int>(
"MaskBrightnessIncrease").getValue());
1094 const int depthThreshold = getProperty<int>(
"MaxDepthDifference").getValue();
1098 if (object->size() == 0)
1103 std::map<unsigned int, int>
1105 std::vector<int> depthsCopy;
1108 for (
unsigned int i = 0; i < getPoseBodyPartMapping(poseModel).size(); i++)
1114 static_cast<int>(point->get2D()._y),
1116 depthStorage[i] = depth;
1117 depthsCopy.push_back(depth);
1122 std::sort(depthsCopy.begin(), depthsCopy.end());
1123 const int medianDepth = depthsCopy.at(depthsCopy.size() / 2);
1124 for (
auto& m : depthStorage)
1126 int depth = m.second;
1127 if (depth > medianDepth + depthThreshold || depth < medianDepth - depthThreshold)
1129 m.second = medianDepth;
1134 for (
unsigned int i = 0; i < op::getPoseBodyPartMapping(poseModel).size(); i++)
1140 imagePoint.x = point->get2D()._x;
1141 imagePoint.y = point->get2D()._y;
1144 calibration->ImageToWorldCoordinates(imagePoint,
1146 static_cast<float>(depthStorage.at(i)),
1147 useDistortionParameters);
1149 point->set3D(
new FramedPosition(Eigen::Vector3f(result.x, result.y, result.z),
1151 localRobot->getName()));
1162 for (
unsigned int i = 0; i < getPoseBodyPartMapping(poseModel).size(); i++)
1168 auto pair = point->getStereo2D();
1169 const Vec2d imagePointL = {pair.first._x, pair.first._y};
1170 const Vec2d imagePointR = {pair.second._x, pair.second._y};
1171 ARMARX_DEBUG <<
"PointL: " << imagePointL.x <<
" " << imagePointL.y;
1172 ARMARX_DEBUG <<
"PointR: " << imagePointR.x <<
" " << imagePointR.y;
1175 PointPair3d* rD =
new PointPair3d();
1176 stereoCalibration->Calculate3DPoint(
1177 imagePointL, imagePointR, result,
false, useDistortionParameters, rD);
1178 ARMARX_DEBUG <<
"IVT- ConnectionLine: " << rD->p1.x <<
" " << rD->p1.y <<
" "
1179 << rD->p1.z <<
" --- " << rD->p2.x <<
" " << rD->p2.y <<
" "
1182 point->set3D(
new FramedPosition(Eigen::Vector3f(result.x, result.y, result.z),
1184 localRobot->getName()));
1193 std::unique_lock lock(keypointManagerMutex);
1194 debugDrawerTopic->removeLayer(layerName +
std::to_string(layerCounter));
1197 if (keypointManager->getData().empty() || !localRobot)
1203 const std::vector<unsigned int>& posePartPairs = op::getPoseBodyPartPairsRender(poseModel);
1204 const std::vector<float> keypointColors = op::getPoseColors(poseModel);
1209 layerCounter = (layerCounter ==
MAX_LAYER - 1) ? 0 : layerCounter + 1;
1211 int objectIndex = 0;
1214 std::string objectName =
"object_" +
std::to_string(objectIndex) +
"_";
1217 for (
unsigned int i = 0; i < posePartPairs.size(); i = i + 2)
1219 KeypointPtr point1 =
object->getNode(posePartPairs[i]);
1220 KeypointPtr point2 =
object->getNode(posePartPairs[i + 1]);
1222 if (point1 && point2)
1227 std::string name = point1->getName() +
"_" + point2->getName();
1228 unsigned int colorIndex = posePartPairs[i + 1] * 3;
1229 DrawColor color({keypointColors[colorIndex + 2] / 255.f,
1230 keypointColors[colorIndex + 1] / 255.f,
1231 keypointColors[colorIndex] / 255.f,
1233 debugDrawerTopic->setLineVisu(layerName +
std::to_string(layerCounter),
1235 new Vector3(p1->x, p1->y, p1->z),
1236 new Vector3(p2->x, p2->y, p2->z),
1245 for (
unsigned int i = 0; i < getPoseBodyPartMapping(poseModel).size(); i++)
1251 auto color24Bit = point->getDominantColor();
1252 auto color = DrawColor{0.0039215f * color24Bit.b,
1253 0.0039215f * color24Bit.g,
1254 0.0039215f * color24Bit.r,
1256 debugDrawerTopic->setSphereVisu(layerName +
std::to_string(layerCounter),
1257 objectName + point->getName(),
1258 new Vector3(p->x, p->y, p->z),
1262 kp.label = point->getName();
1266 kp.confidence = point->getConfidence();
1267 kpm[point->getName()] = kp;
1282 std::vector<int> depths;
1283 for (
int xoffset = -radius; xoffset < radius; xoffset++)
1285 int xo = x + xoffset;
1286 if (xo < 0 || xo > depthImageBuffer->width)
1290 for (
int yoffset = -radius; yoffset < radius; yoffset++)
1292 int yo = y + yoffset;
1293 if (yo < 0 || yo > depthImageBuffer->height)
1299 if (xoffset * xoffset + yoffset * yoffset <= radius * radius)
1301 unsigned int pixelPos =
1302 static_cast<unsigned int>(3 * (yo * depthImageBuffer->width + xo));
1303 int z_value = depthImageBuffer->pixels[pixelPos + 0] +
1304 (depthImageBuffer->pixels[pixelPos + 1] << 8) +
1305 (depthImageBuffer->pixels[pixelPos + 2] << 16);
1308 depths.push_back(z_value);
1313 std::sort(depths.begin(), depths.end());
1315 return depths.empty() ? 0 : depths[depths.size() / 2];