40 usingProxy(getProperty<std::string>(
"RobotStateComponentProxyName").getValue());
42 providerName = getProperty<std::string>(
"providerName").getValue();
46 sensorFrameName = getProperty<std::string>(
"SensorFrameName").getValue();
47 markerFrameName = getProperty<std::string>(
"MarkerName").getValue();
48 handFrameName = getProperty<std::string>(
"HandNameInRobotModel").getValue();
53 offeringTopic(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
64 if (numImages < 1 || numImages > 2)
70 images =
new CByteImage*[numImages];
72 for (
int i = 0 ; i < numImages ; i++)
77 result =
new CByteImage*[numImages];
79 this->robotStatePrx = getProxy<armarx::RobotStateComponentInterfacePrx>(getProperty<std::string>(
"RobotStateComponentProxyName").getValue());
81 ImageDimension dimension(images[0]->width, images[0]->height);
83 enableResultPointClouds<pcl::PointXYZRGBA>(
"MarkerCloud");
84 enableResultPointClouds<pcl::PointXYZRGBA>(
"Filtered_Cloud");
85 this->debugDrawerTopic = getTopic<armarx::DebugDrawerInterfacePrx>(getProperty<std::string>(
"DebugDrawerTopicName").getValue());
90 this->debugDrawerTopic->clearLayer(
"RGBDHandLocalizer");
95 for (
int i = 0; i < numImages; i++)
101 for (
int i = 0; i < numImages; i++)
113 ARMARX_WARNING <<
"Timeout or error while waiting for image data";
127 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr currentPointCloud(
new pcl::PointCloud<pcl::PointXYZRGBA>());
128 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr filteredPointCloud(
new pcl::PointCloud<pcl::PointXYZRGBA>());
130 std::vector<Eigen::Vector3f> medianCoordinates;
135 if (!currentPointCloud->isOrganized())
142 IplImage* iplImage = IplImageAdaptor::Adapt(images[0]);
143 cv::Mat RGBImage = cv::cvarrToMat(iplImage);
146 cv::cvtColor(RGBImage, HSVImage, cv::COLOR_RGB2HSV);
150 cv::Scalar minColor(getProperty<int>(
"hueMin").getValue(),
151 getProperty<int>(
"satMin").getValue(),
152 getProperty<int>(
"valMin").getValue());
154 cv::Scalar maxColor(getProperty<int>(
"hueMax").getValue(),
155 getProperty<int>(
"satMax").getValue(),
156 getProperty<int>(
"valMax").getValue());
157 cv::inRange(HSVImage, minColor, maxColor, mask);
160 cv::erode(mask, mask, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(6, 6)));
161 cv::dilate(mask, mask, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(6, 6)));
163 cv::dilate(mask, mask, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3)));
164 cv::erode(mask, mask, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3)));
174 copy->changeFrame(currentRobot, sensorFrameName);
175 Eigen::Vector3f guessMM =
copy->toEigen();
176 this->cropFilter(currentPointCloud, filteredPointCloud, getProperty<float>(
"uncertaintyMM").getValue(), guessMM);
182 this->calcPositions(mask, filteredPointCloud, medianCoordinates);
185 kinematicHandPosition->changeFrame(currentRobot, markerFrameName);
189 offsetToHand->changeFrame(sharedRobot, sensorFrameName);
192 if (medianCoordinates.size() > 0)
196 for (Eigen::Vector3f currentMedian : medianCoordinates)
200 float currentDist = (kinematicMarkerPosition->toEigen() - currentMedian).
norm();
210 Eigen::Vector3f handPositionEigen = markerPosition->toEigen() + offsetToHand->toEigen();
213 if (getProperty<bool>(
"PrimitiveCalibrationOnStart").getValue())
215 int numCalibrations = 20;
216 if (calibrationCounter < numCalibrations)
219 kinCopy->changeFrame(currentRobot, sensorFrameName);
220 Eigen::Vector3f diff = kinCopy->toEigen() - handPositionEigen;
221 this->calibrationSum = this->calibrationSum + diff;
222 calibrationCounter++;
226 handPositionEigen = handPositionEigen + (calibrationSum / numCalibrations);
235 armarx::FramedPosePtr handRootPose = armarx::FramedPosePtr::dynamicCast(currentRobot->getRobotNode(handFrameName)->getPoseInRootFrame());
239 handOrientation->changeFrame(currentRobot, sensorFrameName);
241 std::scoped_lock lock(positionLock);
243 this->realHandPose =
new armarx::FramedPose(handOrientation->toEigen(), realHandPosition->toEigen(), sensorFrameName, currentRobot->getName());
248 this->debugDrawerTopic->setPoseVisu(
"RGBDHandLocalizer",
249 "Real_Hand_Position",
250 this->realHandPose->toGlobal(currentRobot));
251 this->debugDrawerTopic->setPoseVisu(
"RGBDHandLocalizer",
252 "Kinematic_Hand_Position",
253 handRootPose->toGlobal(currentRobot));
254 this->debugDrawerTopic->setPoseVisu(
"RGBDHandLocalizer",
256 currentRobot->getRobotNode(sensorFrameName)->getGlobalPose());
257 this->debugDrawerTopic->setSphereVisu(
"RGBDHandLocalizer",
260 armarx::DrawColor {1, 1, 0, 0.5},
262 this->debugDrawerTopic->setSphereVisu(
"RGBDHandLocalizer",
263 "MarkerPos_Kinematic",
264 new armarx::Vector3(kinematicMarkerPosition->toGlobalEigen(currentRobot)),
265 armarx::DrawColor {1, 0, 1, 0.5},
278 IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3);
279 cv::Mat outMat = cv::cvarrToMat(img);
280 cv::cvtColor(mask, outMat, cv::COLOR_GRAY2RGB);
282 result[1] = images[0];
283 result[0] = IplImageAdaptor::Adapt(img);
285 cvReleaseImage(&img);
291 void RGBDHandLocalizer::calcPositions(cv::Mat& binaryImage, pcl::PointCloud<pcl::PointXYZRGBA>::Ptr pointcloud, std::vector<Eigen::Vector3f>& medianCoordinates)
293 medianCoordinates.clear();
295 cv::Mat labeledImage;
296 std::vector<std::vector<cv::Point>> blobList;
297 labeler.
labelBlobs(binaryImage, labeledImage, blobList);
299 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr outputCloud(
new pcl::PointCloud<pcl::PointXYZRGBA>());
301 for (std::vector<cv::Point> blob : blobList)
303 Eigen::Vector3f sum = Eigen::Vector3f::Zero();
305 int numberOfPixels = 0;
308 pcl::PointXYZRGBA point3D = pointcloud->at(picturePoint.x, picturePoint.y);
313 outputCloud->push_back(point3D);
315 Eigen::Vector3f vector;
316 vector << point3D.x, point3D.y, point3D.z;
322 if (numberOfPixels != 0)
324 Eigen::Vector3f median = sum / numberOfPixels;
325 float markerRadius = getProperty<float>(
"MarkerRadiusMM").getValue();
326 median = median + markerRadius * median.normalized();
327 medianCoordinates.push_back(median);
330 labeledImage.release();
335 void RGBDHandLocalizer::cropFilter(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr
input, pcl::PointCloud<pcl::PointXYZRGBA>::Ptr output,
float uncertaintyMM, Eigen::Vector3f guessMM)
344 this->cropper.setInputCloud(
input);
345 this->cropper.setKeepOrganized(
true);
346 this->cropper.setMax(Eigen::Vector4f(uncertaintyMM, uncertaintyMM, uncertaintyMM, 1));
347 this->cropper.setMin(Eigen::Vector4f(-uncertaintyMM, -uncertaintyMM, -uncertaintyMM, 1));
348 this->cropper.setTranslation(guessMM);
349 this->cropper.setRotation(Eigen::Vector3f::Zero());
350 this->cropper.filter(*output);
356 memoryx::ObjectLocalizationResultList resultList;
359 if (classNames.size() == 1)
361 if (classNames.at(0) == getProperty<std::string>(
"HandNameInMemory").getValue())
363 if (this->realHandPose)
366 std::scoped_lock lock(positionLock);
368 memoryx::ObjectLocalizationResult localizationResult;
370 localizationResult.objectClassName = getProperty<std::string>(
"HandNameInMemory").getValue();
371 localizationResult.timeStamp = this->timestamp;
372 localizationResult.orientation = this->realHandPose->getOrientation();
373 localizationResult.position = this->realHandPose->getPosition();
374 localizationResult.recognitionCertainty = 1.0;
375 Eigen::Vector3f
mean = Eigen::Vector3f::Zero();
378 localizationResult.positionNoise = dummy;
381 resultList.push_back(localizationResult);
382 ARMARX_INFO <<
"Hand found at: " << localizationResult.position->output();