24 #include "Helpers/helpers.h"
25 #include "../../../vision_algorithms/HandLocalizationWithFingertips/HandLocalisation.h"
26 #include "../../../vision_algorithms/HandLocalizationWithFingertips/Visualization/HandModelVisualizer.h"
32 #include <Calibration/StereoCalibration.h>
33 #include <Image/ByteImage.h>
34 #include <Threading/Threading.h>
35 #include <Image/IplImageAdaptor.h>
36 #include <Image/ImageProcessor.h>
44 #include <RobotAPI/interface/components/ViewSelectionInterface.h>
50 #include <opencv2/video/tracking.hpp>
60 timeOfLastExecution = IceUtil::Time::now();
64 providerName = getProperty<std::string>(
"ImageProviderAdapterName").getValue();
67 robotStateProxyName = getProperty<std::string>(
"RobotStateProxyName").getValue();
70 usingProxy(getProperty<std::string>(
"ObjectMemoryObserverName").getValue());
72 handFrameName = getProperty<std::string>(
"HandFrameName").getValue();
73 cameraFrameName = getProperty<std::string>(
"CameraFrameName").getValue();
75 minNumPixelsInClusterForCollisionDetection = getProperty<int>(
"MinNumPixelsInClusterForCollisionDetection").getValue();
76 minNumPixelsInClusterForCollisionDetection /= clusteringSampleStep * clusteringSampleStep * imageResizeFactorForOpticalFlowCalculation * imageResizeFactorForOpticalFlowCalculation;
78 useHandLocalization = getProperty<bool>(
"UseHandLocalization").getValue();
93 imageProviderPrx = getProxy<ImageProviderInterfacePrx>(providerName);
95 cameraImages =
new CByteImage*[2];
99 resultImages =
new CByteImage*[eNumberOfResultImages];
101 for (
int i = 0; i < eNumberOfResultImages; i++)
108 delete resultImages[eEverything];
109 resultImages[eEverything] =
new CByteImage(3 * cameraImages[0]->width, 2 * cameraImages[0]->height, CByteImage::eRGB24);
111 camImgLeftGrey =
new CByteImage(cameraImages[0]->width, cameraImages[0]->height, CByteImage::eGrayScale);
112 camImgLeftGreySmall =
new CByteImage(cameraImages[0]->width / imageResizeFactorForOpticalFlowCalculation, cameraImages[0]->height / imageResizeFactorForOpticalFlowCalculation, CByteImage::eGrayScale);
114 camImgLeftGreyOldSmall =
new CByteImage(camImgLeftGreySmall);
115 tempImageRGB =
new CByteImage(cameraImages[0]);
116 tempImageRGB1 =
new CByteImage(cameraImages[0]);
117 tempImageRGB2 =
new CByteImage(cameraImages[0]);
118 tempImageRGB3 =
new CByteImage(cameraImages[0]);
119 tempImageRGB4 =
new CByteImage(cameraImages[0]);
120 pSegmentedImage =
new CByteImage(cameraImages[0]);
121 pOpticalFlowClusterImage =
new CByteImage(cameraImages[0]);
124 StereoCalibrationProviderInterfacePrx calibrationProviderPrx = StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderPrx);
126 if (!calibrationProviderPrx)
128 ARMARX_ERROR <<
"Image provider with name " << providerName <<
" is not a StereoCalibrationProvider" << std::endl;
137 robotStateProxy = getProxy<armarx::RobotStateComponentInterfacePrx>(robotStateProxyName);
139 visionx::ImageDimension dim;
140 dim.width = 3 * cameraImages[0]->width;
141 dim.height = 2 * cameraImages[0]->height;
154 oldCollisionProbability = 0;
156 colors =
new int[3 * (maxNumOptFlowClusters + 1)];
158 for (
int j = 0; j < 3 * (maxNumOptFlowClusters + 1); j++)
160 colors[j] = rand() % 220 + 30;
164 handNameInMemoryX = getProperty<std::string>(
"HandNameInMemoryX").getValue();
166 if (this->
getIceManager()->isObjectReachable(getProperty<std::string>(
"ObjectMemoryObserverName").getValue()))
169 objectMemoryObserver = getProxy<memoryx::ObjectMemoryObserverInterfacePrx>(getProperty<std::string>(
"ObjectMemoryObserverName").getValue());
170 handMemoryChannel = armarx::ChannelRefPtr::dynamicCast(objectMemoryObserver->requestObjectClassRepeated(handNameInMemoryX, 200, armarx::DEFAULT_VIEWTARGET_PRIORITY));
172 if (!handMemoryChannel)
174 ARMARX_IMPORTANT_S <<
"Object " << handNameInMemoryX <<
" seems to be unknown to ObjectMemoryObserver";
180 objectMemoryObserver = NULL;
183 listener = getTopic<VisualContactDetectionListenerPrx>(
"VisualContactDetection");
191 bool doSomething =
false;
194 std::unique_lock lock(activationStateMutex);
203 int nNumberImages =
getImages(cameraImages);
206 if (nNumberImages > 0 && active)
208 if ((IceUtil::Time::now() - timeOfLastExecution).toMilliSeconds() >= getProperty<int>(
"MinWaitingTimeBetweenTwoFrames").getValue())
219 timeOfLastExecution = IceUtil::Time::now();
221 ::ImageProcessor::Zero(resultImages[eEverything]);
223 omp_set_nested(
true);
225 #pragma omp parallel sections
234 ARMARX_VERBOSE <<
"localizeHand() took " << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
242 calculateOpticalFlowClusters();
244 ARMARX_VERBOSE <<
"calculateOpticalFlowClusters() took " << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
250 bool collisionDetected = detectCollision();
251 listener->reportContactDetected(collisionDetected);
252 ARMARX_VERBOSE <<
"detectCollision() took " << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
254 start = IceUtil::Time::now();
255 drawVisualization(collisionDetected);
257 ARMARX_VERBOSE <<
"drawVisualization() took " << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
260 ARMARX_VERBOSE <<
"Complete calculation took " << (IceUtil::Time::now() - startAll).toMilliSeconds() <<
" ms";
267 void VisualContactDetection::localizeHand()
270 armarx::PosePtr handNodePosePtr = armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()->getRobotNode(handFrameName)->getPoseInRootFrame());
272 armarx::PosePtr cameraNodePosePtr = armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()->getRobotNode(cameraFrameName)->getPoseInRootFrame());
274 Eigen::Matrix4f handPoseInCameraFrame = cameraNodePose.inverse() * handNodePose;
277 Eigen::Vector4f offsetTCPtoPalm = {0, 0, 0, 1};
278 Eigen::Vector4f palmPosition = cameraNodePose.inverse() * handNodePose * offsetTCPtoPalm;
285 Vec3d tcpPosition = {handPoseInCameraFrame(0, 3), handPoseInCameraFrame(1, 3), handPoseInCameraFrame(2, 3)};
286 Vec3d handNodePosition = {palmPosition(0), palmPosition(1), palmPosition(2)};
287 Mat3d handNodeOrientation = {handPoseInCameraFrame(0, 0), handPoseInCameraFrame(0, 1), handPoseInCameraFrame(0, 2),
288 handPoseInCameraFrame(1, 0), handPoseInCameraFrame(1, 1), handPoseInCameraFrame(1, 2),
289 handPoseInCameraFrame(2, 0), handPoseInCameraFrame(2, 1), handPoseInCameraFrame(2, 2)
298 double* fingerConfig =
new double[6];
302 fingerConfig[0] = 30 *
M_PI / 180;
303 fingerConfig[1] = 5 *
M_PI / 180;
304 fingerConfig[2] = 5 *
M_PI / 180;
305 fingerConfig[3] = 5 *
M_PI / 180;
306 fingerConfig[4] = 5 *
M_PI / 180;
307 fingerConfig[5] = 5 *
M_PI / 180;
312 fingerConfig[0] = 1.57f + robot->getRobotNode(
"Hand Palm 2 R")->getJointValue();
313 fingerConfig[1] = robot->getRobotNode(
"Thumb R J0")->getJointValue();
314 fingerConfig[2] = robot->getRobotNode(
"Thumb R J1")->getJointValue();
315 fingerConfig[3] = 0.5f * (robot->getRobotNode(
"Index R J0")->getJointValue() + robot->getRobotNode(
"Index R J1")->getJointValue());
316 fingerConfig[4] = 0.5f * (robot->getRobotNode(
"Middle R J0")->getJointValue() + robot->getRobotNode(
"Middle R J1")->getJointValue());
317 fingerConfig[5] = 0.25f * (robot->getRobotNode(
"Ring R J0")->getJointValue() + robot->getRobotNode(
"Ring R J1")->getJointValue()
318 + robot->getRobotNode(
"Pinky R J0")->getJointValue() + robot->getRobotNode(
"Pinky R J1")->getJointValue());
323 if (objectMemoryObserver && handMemoryChannel)
325 memoryx::ChannelRefBaseSequence instances = objectMemoryObserver->getObjectInstances(handMemoryChannel);
327 if (instances.size() != 0)
333 armarx::FramedPose handPoseMemory(orientation->toEigen(), position->toEigen(), position->getFrame(), position->agent);
338 if (position->getFrame().compare(cameraFrameName) != 0)
340 auto robot = robotStateProxy->getSynchronizedRobot();
341 Eigen::Matrix4f memoryNodePose = armarx::PosePtr::dynamicCast(robot->getRobotNode(position->getFrame())->getPoseInRootFrame())->toEigen();
342 Eigen::Matrix4f m = cameraNodePose.inverse() * memoryNodePose * handPoseMemory.toEigen();
346 ARMARX_VERBOSE_S <<
"Pose from memory in camera coordinates: " << handPoseMemory;
349 const float ratio = 0.999f;
350 handNodePosition.x = (1.0f - ratio) * handNodePosition.x + ratio * handPoseMemory.position->x;
351 handNodePosition.y = (1.0f - ratio) * handNodePosition.y + ratio * handPoseMemory.position->y;
352 handNodePosition.z = (1.0f - ratio) * handNodePosition.z + ratio * handPoseMemory.position->z;
361 ARMARX_VERBOSE_S <<
"objectMemoryObserver: " << objectMemoryObserver <<
" handMemoryChannel: " << handMemoryChannel;
368 Vec3d xDirection = {100, 0, 0};
369 Vec3d yDirection = {0, 100, 0};
370 Vec3d zDirection = {0, 0, 100};
371 Math3d::MulMatVec(handNodeOrientation, xDirection, tcpPosition, xDirection);
372 Math3d::MulMatVec(handNodeOrientation, yDirection, tcpPosition, yDirection);
373 Math3d::MulMatVec(handNodeOrientation, zDirection, tcpPosition, zDirection);
374 Vec2d tcp, xAxis, yAxis, zAxis;
375 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(tcpPosition, tcp,
false);
376 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(xDirection, xAxis,
false);
377 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(yDirection, yAxis,
false);
378 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(zDirection, zAxis,
false);
379 handModelVisualizer->
DrawLineIntoImage(cameraImages[0], tcp.x, tcp.y, xAxis.x, xAxis.y, 255, 0, 0);
380 handModelVisualizer->
DrawLineIntoImage(cameraImages[0], tcp.x, tcp.y, yAxis.x, yAxis.y, 0, 255, 0);
381 handModelVisualizer->
DrawLineIntoImage(cameraImages[0], tcp.x, tcp.y, zAxis.x, zAxis.y, 0, 0, 255);
385 if (useHandLocalization)
387 double* estimatedConfig =
new double[12];
388 double confidenceRating;
389 handLocalization->
LocaliseHand(cameraImages[0], cameraImages[1], handNodePosition, handNodeOrientation, fingerConfig, estimatedConfig, confidenceRating);
390 delete[] estimatedConfig;
394 handLocalization->
SetSensorConfig(handNodePosition, handNodeOrientation, fingerConfig);
395 handLocalization->
SetResultConfig(handNodePosition, handNodeOrientation, fingerConfig);
400 handModelVisualizer->
UpdateHandModel(localizationResult, drawComplexHandModelInResultImage);
401 std::string output =
"Localization result:";
410 delete[] localizationResult;
411 ::ImageProcessor::Zero(pSegmentedImage);
412 handModelVisualizer->
DrawSegmentedImage(pSegmentedImage, drawComplexHandModelInResultImage);
419 void VisualContactDetection::calculateOpticalFlowClusters()
421 ::ImageProcessor::ConvertImage(cameraImages[0], camImgLeftGrey);
422 ::ImageProcessor::Resize(camImgLeftGrey, camImgLeftGreySmall);
427 ::ImageProcessor::CopyImage(camImgLeftGreySmall, camImgLeftGreyOldSmall);
430 pCamLeftIpl = convertToIplImage(camImgLeftGreySmall);
431 pCamLeftOldIpl = convertToIplImage(camImgLeftGreyOldSmall);
432 cv::Mat mCamLeftMat = cv::cvarrToMat(pCamLeftIpl);
433 cv::Mat mCamLeftOldMat = cv::cvarrToMat(pCamLeftOldIpl);
434 cv::Mat mOpticalFlowMat;
450 cv::calcOpticalFlowFarneback(mCamLeftMat, mCamLeftOldMat, mOpticalFlowMat, 0.5, 5, 20, 7, 7, 1.5, 0);
452 cv::Mat mVisOptFlow(mOpticalFlowMat.size(), CV_32FC3);
455 #pragma omp parallel for schedule(static, 40)
456 for (
int j = 0; j < mOpticalFlowMat.rows; j++)
458 const int l = imageResizeFactorForOpticalFlowCalculation * j;
460 for (
int k = 0, m = 0; k < mOpticalFlowMat.cols; k++, m += imageResizeFactorForOpticalFlowCalculation)
462 mVisOptFlow.at<
cv::Vec3f>(j, k).val[0] = 0.4 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[0];
463 mVisOptFlow.at<
cv::Vec3f>(j, k).val[1] = 0.4 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[1];
464 mVisOptFlow.at<
cv::Vec3f>(j, k).val[2] = 0;
466 for (
int n = 0; n < imageResizeFactorForOpticalFlowCalculation; n++)
468 for (
int o = 0; o < imageResizeFactorForOpticalFlowCalculation; o++)
481 std::vector<std::vector<float> > aPixelsAndFlowDirections;
482 std::vector<float> aPixelPosAndFlowDirection;
483 aPixelPosAndFlowDirection.resize(4);
485 for (
int j = 0; j < mOpticalFlowMat.rows; j += clusteringSampleStep)
487 for (
int k = 0; k < mOpticalFlowMat.cols; k += clusteringSampleStep)
489 aPixelPosAndFlowDirection.at(0) = imageResizeFactorForOpticalFlowCalculation * j;
490 aPixelPosAndFlowDirection.at(1) = imageResizeFactorForOpticalFlowCalculation * k;
491 aPixelPosAndFlowDirection.at(2) = 4000 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[0];
492 aPixelPosAndFlowDirection.at(3) = 4000 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[1];
494 aPixelsAndFlowDirections.push_back(aPixelPosAndFlowDirection);
499 std::vector<std::vector<float> > aZeroMotionCluster;
501 for (
size_t j = 0; j < aPixelsAndFlowDirections.size(); j++)
503 float fAbsMotion = fabs(aPixelsAndFlowDirections.at(j).at(2)) + fabs(aPixelsAndFlowDirections.at(j).at(3));
505 if (fAbsMotion < 350)
507 aZeroMotionCluster.push_back(aPixelsAndFlowDirections.at(j));
508 aPixelsAndFlowDirections.at(j) = aPixelsAndFlowDirections.at(aPixelsAndFlowDirections.size() - 1);
509 aPixelsAndFlowDirections.pop_back();
514 std::vector<std::vector<int> > aOldIndices;
515 const float fBIC = 0.08;
516 clusterXMeans(aPixelsAndFlowDirections, 1, maxNumOptFlowClusters, fBIC, opticalFlowClusters, aOldIndices);
518 opticalFlowClusters.push_back(aZeroMotionCluster);
523 ::ImageProcessor::CopyImage(camImgLeftGreySmall, camImgLeftGreyOldSmall);
529 bool VisualContactDetection::detectCollision()
536 Eigen::Matrix4f handNodePose = armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()->getRobotNode(handFrameName)->getPoseInRootFrame())->toEigen();
537 Vec3d handPosSensor = {handNodePose(0, 3), handNodePose(1, 3), handNodePose(2, 3)};
541 Math3d::SetVec(oldHandPosSensor, handPosSensor);
545 Vec3d pushDirection, pushDirectionNormalized;
547 Math3d::SubtractVecVec(handPosSensor, oldHandPosSensor, pushDirection);
548 Math3d::SetVec(pushDirectionNormalized, pushDirection);
550 ARMARX_INFO <<
"Push direction: " << pushDirection.x <<
" " << pushDirection.y <<
" " << pushDirection.z;
552 if (Math3d::Length(pushDirection) > 0)
554 Math3d::NormalizeVec(pushDirectionNormalized);
555 Math3d::MulVecScalar(pushDirection, pushDetectionBoxForwardOffsetToTCP / Math3d::Length(pushDirection), pushDirection);
559 Eigen::Vector3f forwardAxis;
560 forwardAxis << 0.0f, 1.0f, 1.0f;
561 forwardAxis.normalize();
562 forwardAxis = handNodePose.block<3, 3>(0, 0) * forwardAxis;
563 Vec3d forwardDirection = {forwardAxis(0), forwardAxis(1), forwardAxis(2)};
564 ARMARX_INFO <<
"Angle to forward direction: " << Math3d::ScalarProduct(forwardDirection, pushDirectionNormalized);
570 if ((Math3d::ScalarProduct(forwardDirection, pushDirectionNormalized) < -0.6f) || (Math3d::Length(pushDirection) == 0))
572 ARMARX_INFO <<
"Not checking for collision because arm is not moving forward";
580 Eigen::Vector3f pushDirectionForBox = {pushDirection.x, pushDirection.y, pushDirection.z};
581 forwardAxis *= 1.0f * pushDetectionBoxForwardOffsetToTCP;
582 pushDirectionForBox = 0.5f * (pushDirectionForBox + forwardAxis);
583 Eigen::Matrix4f cameraNodePose = armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()->getRobotNode(cameraFrameName)->getPoseInRootFrame())->toEigen();
584 Eigen::Vector3f pushDirectionInCameraCoords = cameraNodePose.block<3, 3>(0, 0) * pushDirectionForBox;
586 Vec3d handPosPF = {handPosePF(0, 3), handPosePF(1, 3), handPosePF(2, 3)};
587 Vec3d pushTarget = {handPosPF.x + pushDirectionInCameraCoords(0), handPosPF.y + pushDirectionInCameraCoords(1), handPosPF.z + pushDirectionInCameraCoords(2)};
589 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(handPosPF, handPos2D,
false);
590 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(pushTarget, pushTarget2D,
false);
592 const float handCameraDistance = (handNodePose.block<3, 1>(0, 3) - cameraNodePose.block<3, 1>(0, 3)).
norm();
593 const float boxSize = 80.0f;
594 Vec2d pushTargetBoxSize = {boxSize * 600 / handCameraDistance, boxSize * 600 / handCameraDistance};
595 ARMARX_INFO <<
"pushTargetBoxSize: " << pushTargetBoxSize.x;
597 Math2d::SetVec(pushTargetBoxLeftUpperCorner, pushTarget2D.x - pushTargetBoxSize.x, pushTarget2D.y - pushTargetBoxSize.y);
598 Math2d::SetVec(pushTargetBoxRightLowerCorner, pushTarget2D.x + pushTargetBoxSize.x, pushTarget2D.y + pushTargetBoxSize.y);
600 if (pushTargetBoxLeftUpperCorner.x < 0)
602 pushTargetBoxLeftUpperCorner.x = 0;
605 if (pushTargetBoxLeftUpperCorner.y < 0)
607 pushTargetBoxLeftUpperCorner.y = 0;
620 Math3d::SetVec(oldHandPosSensor, handPosSensor);
630 bool bContact =
false;
632 std::vector<int> aNumClusterPointsInPushingBox, aNumClusterPointsInHandArea, aNumClusterPointsInRestOfImage;
634 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
636 aNumClusterPointsInPushingBox.push_back(0);
637 aNumClusterPointsInHandArea.push_back(0);
638 aNumClusterPointsInRestOfImage.push_back(0);
641 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
643 for (
size_t k = 0; k < opticalFlowClusters.at(j).size(); k++)
645 const float y = opticalFlowClusters.at(j).at(k).at(0);
646 const float x = opticalFlowClusters.at(j).at(k).at(1);
651 if (pSegmentedImage->pixels[3 * nIndex])
653 aNumClusterPointsInHandArea.at(j)++;
655 else if (pushTargetBoxLeftUpperCorner.x <= x && x <= pushTargetBoxRightLowerCorner.x && pushTargetBoxLeftUpperCorner.y <= y && y <= pushTargetBoxRightLowerCorner.y)
657 aNumClusterPointsInPushingBox.at(j)++;
661 aNumClusterPointsInRestOfImage.at(j)++;
666 aNumClusterPointsInRestOfImage.at(j)++;
671 float fBestRatio = 0;
674 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
676 if (aNumClusterPointsInPushingBox.at(j) > minNumPixelsInClusterForCollisionDetection)
678 float fRatio = (
float)aNumClusterPointsInPushingBox.at(j) / (
float)(aNumClusterPointsInPushingBox.at(j) + aNumClusterPointsInRestOfImage.at(j));
680 if (fRatio > fBestRatio)
688 ARMARX_LOG <<
"Contact probability: " << fBestRatio;
690 bContact = (fBestRatio > 0.5f && oldCollisionProbability > 0.5);
691 oldCollisionProbability = fBestRatio;
696 ARMARX_LOG <<
"Region size: " << clusteringSampleStep* clusteringSampleStep
697 *imageResizeFactorForOpticalFlowCalculation* imageResizeFactorForOpticalFlowCalculation
698 *aNumClusterPointsInPushingBox.at(nBestIndex);
709 void VisualContactDetection::drawVisualization(
bool collisionDetected)
711 timesOfImageCapture.push_back(IceUtil::Time::now().toMilliSeconds());
713 #pragma omp parallel sections
720 CByteImage* pNew =
new CByteImage(cameraImages[0]);
721 ::ImageProcessor::CopyImage(cameraImages[0], pNew);
722 cameraImagesForSaving.push_back(pNew);
732 handModelVisualizer1->
UpdateHandModel(sensorConfig, drawComplexHandModelInResultImage);
733 delete[] sensorConfig;
734 ::ImageProcessor::CopyImage(cameraImages[0], tempImageRGB1);
737 for (
int i = 0; i < cameraImages[0]->height; i++)
739 for (
int j = 0; j < cameraImages[0]->width; j++)
741 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j)] = tempImageRGB1->pixels[3 * (i * cameraImages[0]->width + j)];
742 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j) + 1] = tempImageRGB1->pixels[3 * (i * cameraImages[0]->width + j) + 1];
743 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j) + 2] = tempImageRGB1->pixels[3 * (i * cameraImages[0]->width + j) + 2];
752 handModelVisualizer2->
UpdateHandModel(localizationResult, drawComplexHandModelInResultImage);
753 delete[] localizationResult;
754 ::ImageProcessor::CopyImage(cameraImages[0], tempImageRGB2);
757 for (
int i = 0; i < cameraImages[0]->height; i++)
759 for (
int j = 0, j2 = cameraImages[0]->width; j < cameraImages[0]->width; j++, j2++)
761 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j2)] = tempImageRGB2->pixels[3 * (i * cameraImages[0]->width + j)];
762 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 1] = tempImageRGB2->pixels[3 * (i * cameraImages[0]->width + j) + 1];
763 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 2] = tempImageRGB2->pixels[3 * (i * cameraImages[0]->width + j) + 2];
769 CByteImage* pNew =
new CByteImage(tempImageRGB2);
770 ::ImageProcessor::CopyImage(tempImageRGB2, pNew);
771 localizationResultImages.push_back(pNew);
779 handModelVisualizer3->
UpdateHandModel(localizationResult, drawComplexHandModelInResultImage);
780 delete[] localizationResult;
781 ::ImageProcessor::CopyImage(cameraImages[1], tempImageRGB3);
784 for (
int i = 0; i < cameraImages[0]->height; i++)
786 for (
int j = 0, j2 = 2 * cameraImages[0]->width; j < cameraImages[0]->width; j++, j2++)
788 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j2)] = tempImageRGB3->pixels[3 * (i * cameraImages[0]->width + j)];
789 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 1] = tempImageRGB3->pixels[3 * (i * cameraImages[0]->width + j) + 1];
790 resultImages[eEverything]->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 2] = tempImageRGB3->pixels[3 * (i * cameraImages[0]->width + j) + 2];
798 for (
int i = 0, i2 = cameraImages[0]->height; i < cameraImages[0]->height; i++, i2++)
800 for (
int j = 0; j < cameraImages[0]->width; j++)
802 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j)] = pSegmentedImage->pixels[3 * (i * cameraImages[0]->width + j)];
803 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j) + 1] = pSegmentedImage->pixels[3 * (i * cameraImages[0]->width + j) + 1];
804 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j) + 2] = pSegmentedImage->pixels[3 * (i * cameraImages[0]->width + j) + 2];
815 ::ImageProcessor::Zero(tempImageRGB4);
830 int nValue = 255 * pVisOptFlowRaw[j];
832 tempImageRGB4->pixels[j] = (0 > nValue) ? 0 : ((255 < nValue) ? 255 : nValue);
835 for (
int i = 0, i2 = cameraImages[0]->height; i < cameraImages[0]->height; i++, i2++)
837 for (
int j = 0, j2 = cameraImages[0]->width; j < cameraImages[0]->width; j++, j2++)
839 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2)] = tempImageRGB4->pixels[3 * (i * cameraImages[0]->width + j)];
840 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 1] = tempImageRGB4->pixels[3 * (i * cameraImages[0]->width + j) + 1];
841 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 2] = tempImageRGB4->pixels[3 * (i * cameraImages[0]->width + j) + 2];
847 CByteImage* pNew =
new CByteImage(tempImageRGB4);
848 ::ImageProcessor::CopyImage(tempImageRGB4, pNew);
849 opticalFlowImages.push_back(pNew);
856 ::ImageProcessor::Zero(pOpticalFlowClusterImage);
858 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
862 for (
size_t k = 0; k < opticalFlowClusters.at(j).size(); k++)
864 int nIndex =
DSHT_IMAGE_WIDTH * opticalFlowClusters.at(j).at(k).at(0) + opticalFlowClusters.at(j).at(k).at(1);
868 for (
int l = 0; l < imageResizeFactorForOpticalFlowCalculation * clusteringSampleStep; l++)
870 for (
int m = 0; m < imageResizeFactorForOpticalFlowCalculation * clusteringSampleStep; m++)
876 pOpticalFlowClusterImage->pixels[3 * nIndex2] = colors[3 * j];
877 pOpticalFlowClusterImage->pixels[3 * nIndex2 + 1] = colors[3 * j + 1];
878 pOpticalFlowClusterImage->pixels[3 * nIndex2 + 2] = colors[3 * j + 2];
888 if (handPos2D.x != -1 || handPos2D.y != -1)
892 if (pSegmentedImage->pixels[j])
894 pOpticalFlowClusterImage->pixels[j] /= 2;
898 handModelVisualizer->
DrawCross(pOpticalFlowClusterImage, handPos2D.x, handPos2D.y, 255, 255, 255);
899 int n = collisionDetected ? 8 : 2;
901 for (
int i = 0; i < n; i++)
903 handModelVisualizer->
DrawLineIntoImage(pOpticalFlowClusterImage, pushTargetBoxLeftUpperCorner.x + i, pushTargetBoxLeftUpperCorner.y + i,
904 pushTargetBoxRightLowerCorner.x - i, pushTargetBoxLeftUpperCorner.y + i, 255, 255, 255);
905 handModelVisualizer->
DrawLineIntoImage(pOpticalFlowClusterImage, pushTargetBoxRightLowerCorner.x - i, pushTargetBoxLeftUpperCorner.y + 1,
906 pushTargetBoxRightLowerCorner.x - i, pushTargetBoxRightLowerCorner.y - i, 255, 255, 255);
907 handModelVisualizer->
DrawLineIntoImage(pOpticalFlowClusterImage, pushTargetBoxRightLowerCorner.x - i, pushTargetBoxRightLowerCorner.y - i,
908 pushTargetBoxLeftUpperCorner.x + i, pushTargetBoxRightLowerCorner.y - i, 255, 255, 255);
909 handModelVisualizer->
DrawLineIntoImage(pOpticalFlowClusterImage, pushTargetBoxLeftUpperCorner.x + i, pushTargetBoxRightLowerCorner.y - i,
910 pushTargetBoxLeftUpperCorner.x + i, pushTargetBoxLeftUpperCorner.y + i, 255, 255, 255);
913 for (
int i = 0, i2 = cameraImages[0]->height; i < cameraImages[0]->height; i++, i2++)
915 for (
int j = 0, j2 = 2 * cameraImages[0]->width; j < cameraImages[0]->width; j++, j2++)
917 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2)] = pOpticalFlowClusterImage->pixels[3 * (i * cameraImages[0]->width + j)];
918 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 1] = pOpticalFlowClusterImage->pixels[3 * (i * cameraImages[0]->width + j) + 1];
919 resultImages[eEverything]->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 2] = pOpticalFlowClusterImage->pixels[3 * (i * cameraImages[0]->width + j) + 2];
926 CByteImage* pNew =
new CByteImage(pOpticalFlowClusterImage);
927 ::ImageProcessor::CopyImage(pOpticalFlowClusterImage, pNew);
928 opticalFlowClusterImages.push_back(pNew);
942 delete [] cameraImages;
946 ARMARX_INFO <<
"Writing all visualization images to disk...";
947 std::string path =
"/localhome/ottenhau/VisColDet/";
948 std::string fileNameCam = path +
"cam0000.bmp";
949 std::string fileNameLocRes = path +
"locres0000.bmp";
950 std::string fileNameOptFlow = path +
"optflow0000.bmp";
951 std::string fileNameOptFlowClus = path +
"optflowclus0000.bmp";
952 std::string fileNameTimes = path +
"times.txt";
953 FILE* pFile = fopen(fileNameTimes.c_str(),
"wt");
954 fprintf(pFile,
"%ld \n", timesOfImageCapture.size() - 1);
956 for (
long i = 0; i < (long)timesOfImageCapture.size() - 1; i++)
958 fprintf(pFile,
"%ld %ld \n", i, timesOfImageCapture.at(i));
959 SetNumberInFileName(fileNameCam, i, 4);
960 SetNumberInFileName(fileNameLocRes, i, 4);
961 SetNumberInFileName(fileNameOptFlow, i, 4);
962 SetNumberInFileName(fileNameOptFlowClus, i, 4);
963 cameraImagesForSaving.at(i)->SaveToFile(fileNameCam.c_str());
964 localizationResultImages.at(i)->SaveToFile(fileNameLocRes.c_str());
965 opticalFlowImages.at(i)->SaveToFile(fileNameOptFlow.c_str());
966 opticalFlowClusterImages.at(i)->SaveToFile(fileNameOptFlowClus.c_str());
967 delete cameraImagesForSaving.at(i);
968 delete localizationResultImages.at(i);
969 delete opticalFlowImages.at(i);
970 delete opticalFlowClusterImages.at(i);
974 ARMARX_VERBOSE <<
"Image " << i <<
" of " << timesOfImageCapture.size();
979 ARMARX_INFO <<
"Finished writing all visualization images to disk";
985 void VisualContactDetection::extractAnglesFromRotationMatrix(
const Mat3d& mat,
Vec3d& angles)
987 angles.y = asin(mat.r3);
988 angles.x = atan2((-mat.r6), (mat.r9));
989 angles.z = atan2((-mat.r2), (mat.r1));
994 IplImage* VisualContactDetection::convertToIplImage(CByteImage* pByteImageRGB)
996 if (pByteImageRGB->type == CByteImage::eRGB24)
1000 for (
int j = 0; j < pByteImageRGB->width * pByteImageRGB->height; j++)
1002 cTemp = pByteImageRGB->pixels[3 * j];
1003 pByteImageRGB->pixels[3 * j] = pByteImageRGB->pixels[3 * j + 2];
1004 pByteImageRGB->pixels[3 * j + 2] = cTemp;
1008 IplImage* pRet = IplImageAdaptor::Adapt(pByteImageRGB);
1014 void VisualContactDetection::clusterXMeans(
const std::vector<std::vector<float> >& aPoints,
const int nMinNumClusters,
const int nMaxNumClusters,
const float fBICFactor, std::vector<std::vector<std::vector<float> > >& aaPointClusters, std::vector<std::vector<int> >& aaOldIndices)
1016 aaPointClusters.clear();
1017 aaOldIndices.clear();
1018 const int nNumberOfSamples = aPoints.size();
1020 if (nNumberOfSamples < nMaxNumClusters)
1030 const int nNumberOfDifferentInitialisations = 4;
1034 const int nDimension = aPoints.at(0).size();
1035 mSamples.create(nNumberOfSamples, nDimension, CV_32FC1);
1037 for (
int i = 0; i < nNumberOfSamples; i++)
1039 for (
int j = 0; j < nDimension; j++)
1041 mSamples.at<
float>(i, j) = aPoints.at(i).at(j);
1045 std::vector<std::vector<std::vector<float> > >* aaPointClustersForAllK =
new std::vector<std::vector<std::vector<float> > >[nMaxNumClusters + 1];
1046 std::vector<std::vector<int> >* aaOldIndicesForAllK =
new std::vector<std::vector<int> >[nMaxNumClusters + 1];
1051 double dMinBIC = 10000000;
1052 int nOptK = nMinNumClusters;
1054 #pragma omp parallel for schedule(dynamic, 1)
1055 for (
int k = nMaxNumClusters; k >= nMinNumClusters; k--)
1057 double dKMeansCompactness, dLogVar, dBIC;
1058 cv::Mat mClusterLabelsLocal;
1059 mClusterLabelsLocal.create(nNumberOfSamples, 1, CV_32SC1);
1060 cv::Mat mClusterCentersLocal;
1061 dKMeansCompactness = cv::kmeans(mSamples, k, mClusterLabelsLocal, tTerminationCriteria, nNumberOfDifferentInitialisations, cv::KMEANS_RANDOM_CENTERS, mClusterCentersLocal);
1063 const int nNumberOfFreeParameters = (k - 1) + (nDimension * k) + k;
1064 dLogVar = log(dKMeansCompactness);
1065 dBIC = fBICFactor * 0.35 * dLogVar + ((double)nNumberOfFreeParameters / (
double)nNumberOfSamples) * log((
double)nNumberOfSamples);
1067 #pragma omp critical
1074 if (dBIC == dMinBIC)
1076 std::vector<float> vPoint;
1077 vPoint.resize(nDimension);
1079 for (
int i = 0; i < k; i++)
1081 std::vector<std::vector<float> > aNewCluster;
1082 aaPointClustersForAllK[k].push_back(aNewCluster);
1083 std::vector<int> aClusterIndices;
1084 aaOldIndicesForAllK[k].push_back(aClusterIndices);
1087 for (
int i = 0; i < nNumberOfSamples; i++)
1089 const int nLabel = mClusterLabelsLocal.at<
int>(i, 0);
1091 if ((nLabel >= 0) && (nLabel < k))
1093 for (
int j = 0; j < nDimension; j++)
1095 vPoint.at(j) = mSamples.at<
float>(i, j);
1098 aaPointClustersForAllK[k].at(nLabel).push_back(vPoint);
1099 aaOldIndicesForAllK[k].at(nLabel).push_back(i);
1114 aaPointClusters = aaPointClustersForAllK[nOptK];
1115 aaOldIndices = aaOldIndicesForAllK[nOptK];
1117 delete[] aaPointClustersForAllK;
1118 delete[] aaOldIndicesForAllK;
1134 visionx::FramedPositionBaseList
ret;
1137 for (
size_t i = 0; i < fingertipPositions.size(); i++)
1139 Eigen::Vector3f position;
1140 position << fingertipPositions.at(i).x, fingertipPositions.at(i).y, fingertipPositions.at(i).z;
1152 std::unique_lock lock(activationStateMutex);
1161 int nNumberImages =
getImages(cameraImages);
1163 ::ImageProcessor::ConvertImage(cameraImages[0], camImgLeftGrey);
1164 ::ImageProcessor::Resize(camImgLeftGrey, camImgLeftGreyOldSmall);
1166 Eigen::Matrix4f handNodePose = armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()->getRobotNode(handFrameName)->getPoseInRootFrame())->toEigen();
1167 Math3d::SetVec(oldHandPosSensor, handNodePose(0, 3), handNodePose(1, 3), handNodePose(2, 3));
1170 timeOfLastExecution = IceUtil::Time::now();
1171 oldCollisionProbability = 0;
1179 std::unique_lock lock(activationStateMutex);
1186 void VisualContactDetection::SetNumberInFileName(std::string& sFileName,
int nNumber,
int nNumDigits)
1188 for (
int i = 0; i < nNumDigits; i++)
1190 int nDecimalDivisor = 1;
1192 for (
int j = 0; j < i; j++)
1194 nDecimalDivisor *= 10;
1197 sFileName.at(sFileName.length() - (5 + i)) =
'0' + (nNumber / nDecimalDivisor) % 10;