27 #include <openpose/pose/poseParameters.hpp>
28 #include <openpose/pose/poseParametersRender.hpp>
31 #include <Image/IplImageAdaptor.h>
32 #include <Image/PrimitivesDrawer.h>
33 #include <Image/ImageProcessor.h>
51 inline int positiveIntRound(
const T a)
61 setupOpenPoseEnvironment();
65 void OpenPoseAdapter::setupOpenPoseEnvironment()
73 poseModel = op::flagsToPoseModel(op_model_pose_conv);
78 const op::Point<int> netInputSize = op::flagsToPoint(op_net_resolution_conv,
"-1x368");
79 const op::Point<int> outputSize = op::flagsToPoint(op_output_resolution_conv,
"-1x-1");
81 #if (OPENPOSE_VERSION_MAJOR > 1) || (OPENPOSE_VERSION_MAJOR == 1 && OPENPOSE_VERSION_MINOR > 7) || (OPENPOSE_VERSION_MAJOR == 1 && OPENPOSE_VERSION_MINOR == 7 && OPENPOSE_VERSION_PATCH > 0)
97 ARMARX_ERROR <<
"Could not find model folder at " << modelFolder;
100 if (!modelFolder.empty() && *modelFolder.rbegin() !=
'/')
104 ARMARX_INFO <<
"Found model path at: " << modelFolder;
117 IplImage* iplImage = IplImageAdaptor::Adapt(inputImage);
118 cv::Mat opInputImage = cv::cvarrToMat(iplImage);
119 const op::Point<int> imageSize {opInputImage.cols, opInputImage.rows};
122 std::vector<double> scaleInputToNetInputs;
123 std::vector<op::Point<int>> netInputSizes;
124 double scaleInputToOutput;
125 op::Point<int> outputResolution;
126 std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution) =
scaleAndSizeExtractor->extract(imageSize);
130 const auto netInputArray =
cvMatToOpInput->createArray(inputImage_conv, scaleInputToNetInputs, netInputSizes);
136 return poseKeypoints;
144 HumanPose2DMap ice_entities;
145 const std::map<unsigned int, std::string> poseBodyPartMapping = op::getPoseBodyPartMapping(
poseModel);
147 if (op_keypoints.getSize().empty())
152 int entities = op_keypoints.getSize().at(0);
153 int points = op_keypoints.getSize().at(1);
158 for (
int i = 0; i < entities; i++)
162 ice_entities[entity_id] = HumanPose2D();
163 Keypoint2DMap ice_keypoint_map;
164 for (
int id = 0;
id < points;
id++)
167 float x = op_keypoints.at({i, id, 0});
168 float y = op_keypoints.at({i, id, 1});
169 float c = op_keypoints.at({i, id, 2});
170 if (x == 0.0f && y == 0.0f &&
c == 0.0f)
175 keypoint.label = poseBodyPartMapping.at(
id);
178 keypoint.confidence =
c;
180 ice_keypoint_map[keypoint.label] = keypoint;
185 ice_entities[entity_id].keypointMap = ice_keypoint_map;
194 if (point.x < 0 || point.y < 0 || point.x >= image.width || point.y >= image.height)
195 return DrawColor24Bit {0, 0, 0};
196 int divisor = 256 / 3;
197 typedef std::tuple<Ice::Byte, Ice::Byte, Ice::Byte> RGBTuple;
198 std::map<RGBTuple, int> histogram;
199 int halfWindowSize =
static_cast<int>(windowSize * 0.5);
200 int left = std::max<int>(0,
static_cast<int>(point.x) - halfWindowSize);
201 int top = std::max<int>(0,
static_cast<int>(point.y) - halfWindowSize);
202 int right = std::min<int>(image.width,
static_cast<int>(point.x) + halfWindowSize);
203 int bottom = std::min<int>(image.height,
static_cast<int>(point.y) + halfWindowSize);
205 for (
int x = left; x < right; x++)
207 for (
int y = top; y < bottom; y++)
209 int pixelPos = (y * image.width + x) * 3;
210 auto tuple = std::make_tuple<Ice::Byte, Ice::Byte, Ice::Byte>(
static_cast<Ice::Byte
>(image.pixels[pixelPos] / divisor),
211 static_cast<Ice::Byte
>(image.pixels[pixelPos + 1] / divisor),
212 static_cast<Ice::Byte
>(image.pixels[pixelPos + 2] / divisor));
213 if (histogram.count(tuple))
215 histogram.at(tuple)++;
219 histogram[tuple] = 1;
224 float maxHistogramValue = 0;
225 RGBTuple dominantColor;
226 for (
auto& pair : histogram)
228 if (pair.second > maxHistogramValue)
230 dominantColor = pair.first;
231 maxHistogramValue = pair.second;
234 auto rgb = DrawColor24Bit {
static_cast<Ice::Byte
>(std::get<0>(dominantColor) * divisor),
235 static_cast<Ice::Byte
>(std::get<1>(dominantColor) * divisor),
236 static_cast<Ice::Byte
>(std::get<2>(dominantColor) * divisor)};
244 resultImage.Set(inputImage.width, inputImage.height, inputImage.type);
245 ::ImageProcessor::CopyImage(&inputImage, &resultImage);
247 if (keypoints.getSize().empty())
252 const std::vector<unsigned int>& posePartPairs = op::getPoseBodyPartPairsRender(
poseModel);
255 std::vector<float> keypointColors = op::getPoseColors(
poseModel);
257 const auto thicknessCircleRatio = 1.f / 75.f;
258 const auto thicknessLineRatioWRTCircle = 0.75f;
259 const auto area = inputImage.width * inputImage.height;
260 const int numberKeypoints = keypoints.getSize(1);
262 for (
int person = 0 ; person < keypoints.getSize(0) ; person++)
264 const auto personRectangle = op::getKeypointsRectangle(keypoints, person, 0.1f);
265 if (personRectangle.area() > 0)
268 const auto ratioAreas = op::fastMin(1.f, op::fastMax(personRectangle.width /
static_cast<float>(inputImage.width),
269 personRectangle.height /
static_cast<float>(inputImage.height)));
270 const auto thicknessRatio = op::fastMax(positiveIntRound<float>(
static_cast<float>(
std::sqrt(area))
271 * thicknessCircleRatio * ratioAreas), 2);
273 const auto thicknessCircle = op::fastMax(1, (ratioAreas > 0.05f ? thicknessRatio : -1));
274 const auto thicknessLine = op::fastMax(1, positiveIntRound(thicknessRatio * thicknessLineRatioWRTCircle));
275 const auto radius = thicknessRatio / 2;
278 for (
unsigned int i = 0; i < posePartPairs.size(); i = i + 2)
280 const int index1 = (person * numberKeypoints +
static_cast<int>(posePartPairs[i])) * keypoints.getSize(2);
281 const int index2 = (person * numberKeypoints +
static_cast<int>(posePartPairs[i + 1])) * keypoints.getSize(2);
283 float x1 = keypoints[index1 + 0];
284 float y1 = keypoints[index1 + 1];
285 float x2 = keypoints[index2 + 0];
286 float y2 = keypoints[index2 + 1];
288 if (!(x1 == 0.0f && y1 == 0.0f) && !(x2 == 0.0f && y2 == 0.0f))
290 if (keypoints[index1 + 2] > renderThreshold && keypoints[index2 + 2] > renderThreshold)
292 unsigned int colorIndex = posePartPairs[i + 1] * 3;
293 ::PrimitivesDrawer::DrawLine(&resultImage,
296 static_cast<int>(keypointColors[colorIndex + 2]),
297 static_cast<int>(keypointColors[colorIndex + 1]),
298 static_cast<int>(keypointColors[colorIndex + 0]),
305 for (
int i = 0; i < numberKeypoints; i++)
307 const int index = (person * numberKeypoints + i) * keypoints.getSize(2);
308 float x = keypoints[
index + 0];
309 float y = keypoints[
index + 1];
311 if (!(x == 0.0f && y == 0.0f) && keypoints[
index + 2] > renderThreshold)
313 unsigned int colorIndex =
static_cast<unsigned int>(i * 3);
315 ::PrimitivesDrawer::DrawCircle(&resultImage,
319 static_cast<int>(keypointColors[colorIndex + 2]),
320 static_cast<int>(keypointColors[colorIndex + 1]),
321 static_cast<int>(keypointColors[colorIndex + 0]),