31 OpenPoseEstimation::setupPropertyDefinitions(def);
33 def->optional(radius,
"DepthMedianRadius",
"Depth Median Radius");
34 def->optional(maxDepth,
"MaxDepth",
"Pixels with a distance higher than this value are masked out. Only for depth camera mode.", PropertyDefinitionBase::eModifiable);
35 def->optional(maxDepthDifference,
"MaxDepthDifference",
"Allowed difference of depth value for one keypoint to median of all keypoints.", PropertyDefinitionBase::eModifiable);
36 def->optional(cameraNodeName,
"CameraNodeName");
41 OpenPoseEstimation::setupLocalVariables();
46 OpenPoseEstimation::destroyLocalVariables();
51 if (!localRobot || !running3D_is_possible || !running3D)
56 RemoteRobot::synchronizeLocalCloneToTimestamp(localRobot, robotStateInterface, timestamp_of_update);
58 const int depthThreshold = maxDepthDifference;
59 openposeResult3D.clear();
61 for (
const auto& entities_iterator : openposeResult)
63 const std::string& name = entities_iterator->first;
64 const Entity2D& entity = entities_iterator->second;
66 if (entity.keypointMap.size() == 0)
71 std::map<std::string, int> depthStorage;
72 std::vector<int> depthsCopy;
75 for (
const auto& entity_iterator : entity.keypointMap)
77 const std::string& kp_name = entities_iterator->first;
78 const Keypoint2D& point = entities_iterator->second;
80 int depth = getMedianDepthFromImage(
static_cast<int>(point.x),
static_cast<int>(point.y), radius);
81 depthStorage[kp_name] = depth;
82 depthsCopy.push_back(depth);
86 std::sort(depthsCopy.begin(), depthsCopy.end());
87 const int medianDepth = depthsCopy.at(depthsCopy.size() / 2);
88 for (
auto& depthStorage_iterator : depthStorage)
90 const std::string& storage_name = depthStorage_iterator->first;
91 int& depth = depthStorage_iterator->second;
93 if (depth > medianDepth + depthThreshold || depth < medianDepth - depthThreshold)
101 openposeResult3D[name] = Entity3D();
102 for (
const auto& entity_iterator : entity.keypointMap)
104 const std::string& kp_name = entity_iterator->first;
105 const Keypoint3D& point = entity_iterator->second;
108 imagePoint.x = point.x;
109 imagePoint.y = point.y;
113 calibration->ImageToWorldCoordinates(imagePoint, result,
static_cast<float>(depthStorage.at(i)), useDistortionParameters);
116 openposeResult3D[name].keypointMap[kp_name].x = result.x;
117 openposeResult3D[name].keypointMap[kp_name].y = result.y;
118 openposeResult3D[name].keypointMap[kp_name].z = result.z;
127 int OpenPose3DDepthImageConverter::getMedianDepthFromImage(
int x,
int y,
int radius)
const
129 std::vector<int> depths;
130 for (
int xoffset = -radius; xoffset < radius; xoffset++)
132 int xo = x + xoffset;
133 if (xo < 0 || xo > depthImageBuffer->width)
137 for (
int yoffset = -radius; yoffset < radius; yoffset++)
139 int yo = y + yoffset;
140 if (yo < 0 || yo > depthImageBuffer->height)
146 if (xoffset * xoffset + yoffset * yoffset <= radius * radius)
148 unsigned int pixelPos =
static_cast<unsigned int>(3 * (yo * depthImageBuffer->width + xo));
149 int z_value = depthImageBuffer->pixels[pixelPos + 0]
150 + (depthImageBuffer->pixels[pixelPos + 1] << 8)
151 + (depthImageBuffer->pixels[pixelPos + 2] << 16);
154 depths.push_back(z_value);
159 std::sort(depths.begin(), depths.end());
161 return depths.empty() ? 0 : depths[depths.size() / 2];
165 void OpenPose3DDepthImageConverter::maskOutBasedOnDepth(CByteImage& image,
int maxDepth)
167 std::unique_lock lock(depthImageBufferMutex);
173 int pixelCount = depthImageBuffer->width * depthImageBuffer->height;
174 int depthThresholdmm = maxDepth;
175 CByteImage maskImage(depthImageBuffer->width, depthImageBuffer->height, CByteImage::eGrayScale);
176 for (
int i = 0; i < pixelCount; i += 1)
178 int z_value = depthImageBuffer->pixels[i * 3 + 0]
179 + (depthImageBuffer->pixels[i * 3 + 1] << 8)
180 + (depthImageBuffer->pixels[i * 3 + 2] << 16);
181 maskImage.pixels[i] = z_value > depthThresholdmm || z_value == 0 ? 0 : 255;
184 ::ImageProcessor::Erode(&maskImage, &maskImage, 5);
185 ::ImageProcessor::Dilate(&maskImage, &maskImage, 20);
186 for (
int i = 0; i < pixelCount; i += 1)
188 if (maskImage.pixels[i] == 0)
190 image.pixels[i * 3] = 0;
191 image.pixels[i * 3 + 1] = 255;
192 image.pixels[i * 3 + 2] = 0;