25 #include "../../../vision_algorithms/HandLocalizationWithFingertips/HandLocalisation.h"
26 #include "../../../vision_algorithms/HandLocalizationWithFingertips/Visualization/HandModelVisualizer.h"
27 #include "Helpers/helpers.h"
33 #include <Calibration/StereoCalibration.h>
34 #include <Image/ByteImage.h>
35 #include <Image/ImageProcessor.h>
36 #include <Image/IplImageAdaptor.h>
37 #include <Threading/Threading.h>
45 #include <RobotAPI/interface/components/ViewSelectionInterface.h>
50 #include <opencv2/video/tracking.hpp>
61 timeOfLastExecution = IceUtil::Time::now();
65 providerName = getProperty<std::string>(
"ImageProviderAdapterName").getValue();
68 robotStateProxyName = getProperty<std::string>(
"RobotStateProxyName").getValue();
71 usingProxy(getProperty<std::string>(
"ObjectMemoryObserverName").getValue());
73 handFrameName = getProperty<std::string>(
"HandFrameName").getValue();
74 cameraFrameName = getProperty<std::string>(
"CameraFrameName").getValue();
76 minNumPixelsInClusterForCollisionDetection =
77 getProperty<int>(
"MinNumPixelsInClusterForCollisionDetection").getValue();
78 minNumPixelsInClusterForCollisionDetection /= clusteringSampleStep * clusteringSampleStep *
79 imageResizeFactorForOpticalFlowCalculation *
80 imageResizeFactorForOpticalFlowCalculation;
82 useHandLocalization = getProperty<bool>(
"UseHandLocalization").getValue();
95 imageProviderPrx = getProxy<ImageProviderInterfacePrx>(providerName);
97 cameraImages =
new CByteImage*[2];
101 resultImages =
new CByteImage*[eNumberOfResultImages];
103 for (
int i = 0; i < eNumberOfResultImages; i++)
109 delete resultImages[eEverything];
110 resultImages[eEverything] =
new CByteImage(
111 3 * cameraImages[0]->width, 2 * cameraImages[0]->height, CByteImage::eRGB24);
114 new CByteImage(cameraImages[0]->width, cameraImages[0]->height, CByteImage::eGrayScale);
115 camImgLeftGreySmall =
116 new CByteImage(cameraImages[0]->width / imageResizeFactorForOpticalFlowCalculation,
117 cameraImages[0]->height / imageResizeFactorForOpticalFlowCalculation,
118 CByteImage::eGrayScale);
120 camImgLeftGreyOldSmall =
new CByteImage(camImgLeftGreySmall);
121 tempImageRGB =
new CByteImage(cameraImages[0]);
122 tempImageRGB1 =
new CByteImage(cameraImages[0]);
123 tempImageRGB2 =
new CByteImage(cameraImages[0]);
124 tempImageRGB3 =
new CByteImage(cameraImages[0]);
125 tempImageRGB4 =
new CByteImage(cameraImages[0]);
126 pSegmentedImage =
new CByteImage(cameraImages[0]);
127 pOpticalFlowClusterImage =
new CByteImage(cameraImages[0]);
130 StereoCalibrationProviderInterfacePrx calibrationProviderPrx =
131 StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderPrx);
133 if (!calibrationProviderPrx)
135 ARMARX_ERROR <<
"Image provider with name " << providerName
136 <<
" is not a StereoCalibrationProvider" << std::endl;
145 robotStateProxy = getProxy<armarx::RobotStateComponentInterfacePrx>(robotStateProxyName);
147 visionx::ImageDimension dim;
148 dim.width = 3 * cameraImages[0]->width;
149 dim.height = 2 * cameraImages[0]->height;
153 handLocalization =
new CHandLocalisation(getProperty<int>(
"NumberOfParticles").getValue(),
166 oldCollisionProbability = 0;
168 colors =
new int[3 * (maxNumOptFlowClusters + 1)];
170 for (
int j = 0; j < 3 * (maxNumOptFlowClusters + 1); j++)
172 colors[j] = rand() % 220 + 30;
176 handNameInMemoryX = getProperty<std::string>(
"HandNameInMemoryX").getValue();
179 getProperty<std::string>(
"ObjectMemoryObserverName").getValue()))
182 objectMemoryObserver = getProxy<memoryx::ObjectMemoryObserverInterfacePrx>(
183 getProperty<std::string>(
"ObjectMemoryObserverName").getValue());
185 armarx::ChannelRefPtr::dynamicCast(objectMemoryObserver->requestObjectClassRepeated(
186 handNameInMemoryX, 200, armarx::DEFAULT_VIEWTARGET_PRIORITY));
188 if (!handMemoryChannel)
191 <<
" seems to be unknown to ObjectMemoryObserver";
197 objectMemoryObserver = NULL;
200 listener = getTopic<VisualContactDetectionListenerPrx>(
"VisualContactDetection");
206 bool doSomething =
false;
209 std::unique_lock lock(activationStateMutex);
218 int nNumberImages =
getImages(cameraImages);
221 if (nNumberImages > 0 && active)
223 if ((IceUtil::Time::now() - timeOfLastExecution).toMilliSeconds() >=
224 getProperty<int>(
"MinWaitingTimeBetweenTwoFrames").getValue())
235 timeOfLastExecution = IceUtil::Time::now();
237 ::ImageProcessor::Zero(resultImages[eEverything]);
239 omp_set_nested(
true);
241 #pragma omp parallel sections
251 << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
259 calculateOpticalFlowClusters();
262 << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
268 bool collisionDetected = detectCollision();
269 listener->reportContactDetected(collisionDetected);
271 << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
273 start = IceUtil::Time::now();
274 drawVisualization(collisionDetected);
277 << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
281 << (IceUtil::Time::now() - startAll).toMilliSeconds() <<
" ms";
286 VisualContactDetection::localizeHand()
290 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
291 ->getRobotNode(handFrameName)
292 ->getPoseInRootFrame());
295 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
296 ->getRobotNode(cameraFrameName)
297 ->getPoseInRootFrame());
299 Eigen::Matrix4f handPoseInCameraFrame = cameraNodePose.inverse() * handNodePose;
302 Eigen::Vector4f offsetTCPtoPalm = {0, 0, 0, 1};
303 Eigen::Vector4f palmPosition = cameraNodePose.inverse() * handNodePose * offsetTCPtoPalm;
310 Vec3d tcpPosition = {
311 handPoseInCameraFrame(0, 3), handPoseInCameraFrame(1, 3), handPoseInCameraFrame(2, 3)};
312 Vec3d handNodePosition = {palmPosition(0), palmPosition(1), palmPosition(2)};
313 Mat3d handNodeOrientation = {handPoseInCameraFrame(0, 0),
314 handPoseInCameraFrame(0, 1),
315 handPoseInCameraFrame(0, 2),
316 handPoseInCameraFrame(1, 0),
317 handPoseInCameraFrame(1, 1),
318 handPoseInCameraFrame(1, 2),
319 handPoseInCameraFrame(2, 0),
320 handPoseInCameraFrame(2, 1),
321 handPoseInCameraFrame(2, 2)};
329 double* fingerConfig =
new double[6];
333 fingerConfig[0] = 30 *
M_PI / 180;
334 fingerConfig[1] = 5 *
M_PI / 180;
335 fingerConfig[2] = 5 *
M_PI / 180;
336 fingerConfig[3] = 5 *
M_PI / 180;
337 fingerConfig[4] = 5 *
M_PI / 180;
338 fingerConfig[5] = 5 *
M_PI / 180;
343 fingerConfig[0] = 1.57f + robot->getRobotNode(
"Hand Palm 2 R")->getJointValue();
344 fingerConfig[1] = robot->getRobotNode(
"Thumb R J0")->getJointValue();
345 fingerConfig[2] = robot->getRobotNode(
"Thumb R J1")->getJointValue();
347 0.5f * (robot->getRobotNode(
"Index R J0")->getJointValue() +
348 robot->getRobotNode(
"Index R J1")->getJointValue());
350 0.5f * (robot->getRobotNode(
"Middle R J0")->getJointValue() +
351 robot->getRobotNode(
"Middle R J1")->getJointValue());
353 0.25f * (robot->getRobotNode(
"Ring R J0")->getJointValue() +
354 robot->getRobotNode(
"Ring R J1")->getJointValue() +
355 robot->getRobotNode(
"Pinky R J0")->getJointValue() +
356 robot->getRobotNode(
"Pinky R J1")->getJointValue());
361 if (objectMemoryObserver && handMemoryChannel)
363 memoryx::ChannelRefBaseSequence instances =
364 objectMemoryObserver->getObjectInstances(handMemoryChannel);
366 if (instances.size() != 0)
371 armarx::ChannelRefPtr::dynamicCast(instances.front())
374 armarx::ChannelRefPtr::dynamicCast(instances.front())
378 position->getFrame(),
384 if (position->getFrame().compare(cameraFrameName) != 0)
386 auto robot = robotStateProxy->getSynchronizedRobot();
388 armarx::PosePtr::dynamicCast(
389 robot->getRobotNode(position->getFrame())->getPoseInRootFrame())
392 cameraNodePose.inverse() * memoryNodePose * handPoseMemory.toEigen();
396 ARMARX_VERBOSE_S <<
"Pose from memory in camera coordinates: " << handPoseMemory;
399 const float ratio = 0.999f;
401 (1.0f - ratio) * handNodePosition.x + ratio * handPoseMemory.position->x;
403 (1.0f - ratio) * handNodePosition.y + ratio * handPoseMemory.position->y;
405 (1.0f - ratio) * handNodePosition.z + ratio * handPoseMemory.position->z;
415 <<
" handMemoryChannel: " << handMemoryChannel;
422 Vec3d xDirection = {100, 0, 0};
423 Vec3d yDirection = {0, 100, 0};
424 Vec3d zDirection = {0, 0, 100};
425 Math3d::MulMatVec(handNodeOrientation, xDirection, tcpPosition, xDirection);
426 Math3d::MulMatVec(handNodeOrientation, yDirection, tcpPosition, yDirection);
427 Math3d::MulMatVec(handNodeOrientation, zDirection, tcpPosition, zDirection);
428 Vec2d tcp, xAxis, yAxis, zAxis;
429 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
430 tcpPosition, tcp,
false);
431 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
432 xDirection, xAxis,
false);
433 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
434 yDirection, yAxis,
false);
435 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
436 zDirection, zAxis,
false);
438 cameraImages[0], tcp.x, tcp.y, xAxis.x, xAxis.y, 255, 0, 0);
440 cameraImages[0], tcp.x, tcp.y, yAxis.x, yAxis.y, 0, 255, 0);
442 cameraImages[0], tcp.x, tcp.y, zAxis.x, zAxis.y, 0, 0, 255);
446 if (useHandLocalization)
448 double* estimatedConfig =
new double[12];
449 double confidenceRating;
457 delete[] estimatedConfig;
461 handLocalization->
SetSensorConfig(handNodePosition, handNodeOrientation, fingerConfig);
462 handLocalization->
SetResultConfig(handNodePosition, handNodeOrientation, fingerConfig);
467 handModelVisualizer->
UpdateHandModel(localizationResult, drawComplexHandModelInResultImage);
468 std::string output =
"Localization result:";
477 delete[] localizationResult;
478 ::ImageProcessor::Zero(pSegmentedImage);
479 handModelVisualizer->
DrawSegmentedImage(pSegmentedImage, drawComplexHandModelInResultImage);
483 VisualContactDetection::calculateOpticalFlowClusters()
485 ::ImageProcessor::ConvertImage(cameraImages[0], camImgLeftGrey);
486 ::ImageProcessor::Resize(camImgLeftGrey, camImgLeftGreySmall);
491 ::ImageProcessor::CopyImage(camImgLeftGreySmall, camImgLeftGreyOldSmall);
494 pCamLeftIpl = convertToIplImage(camImgLeftGreySmall);
495 pCamLeftOldIpl = convertToIplImage(camImgLeftGreyOldSmall);
496 cv::Mat mCamLeftMat = cv::cvarrToMat(pCamLeftIpl);
497 cv::Mat mCamLeftOldMat = cv::cvarrToMat(pCamLeftOldIpl);
498 cv::Mat mOpticalFlowMat;
514 cv::calcOpticalFlowFarneback(mCamLeftMat,
525 cv::Mat mVisOptFlow(mOpticalFlowMat.size(), CV_32FC3);
528 #pragma omp parallel for schedule(static, 40)
529 for (
int j = 0; j < mOpticalFlowMat.rows; j++)
531 const int l = imageResizeFactorForOpticalFlowCalculation * j;
533 for (
int k = 0, m = 0; k < mOpticalFlowMat.cols;
534 k++, m += imageResizeFactorForOpticalFlowCalculation)
537 0.4 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[0];
539 0.4 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[1];
540 mVisOptFlow.at<
cv::Vec3f>(j, k).val[2] = 0;
542 for (
int n = 0; n < imageResizeFactorForOpticalFlowCalculation; n++)
544 for (
int o = 0; o < imageResizeFactorForOpticalFlowCalculation; o++)
547 0.5f * (mVisOptFlow.at<
cv::Vec3f>(j, k).val[2] + 1);
549 0.5f * (mVisOptFlow.at<
cv::Vec3f>(j, k).val[1] + 1);
551 0.5f * (mVisOptFlow.at<
cv::Vec3f>(j, k).val[0] + 1);
559 std::vector<std::vector<float>> aPixelsAndFlowDirections;
560 std::vector<float> aPixelPosAndFlowDirection;
561 aPixelPosAndFlowDirection.resize(4);
563 for (
int j = 0; j < mOpticalFlowMat.rows; j += clusteringSampleStep)
565 for (
int k = 0; k < mOpticalFlowMat.cols; k += clusteringSampleStep)
567 aPixelPosAndFlowDirection.at(0) = imageResizeFactorForOpticalFlowCalculation * j;
568 aPixelPosAndFlowDirection.at(1) = imageResizeFactorForOpticalFlowCalculation * k;
569 aPixelPosAndFlowDirection.at(2) = 4000 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[0];
570 aPixelPosAndFlowDirection.at(3) = 4000 * mOpticalFlowMat.at<
cv::Vec2f>(j, k).val[1];
572 aPixelsAndFlowDirections.push_back(aPixelPosAndFlowDirection);
577 std::vector<std::vector<float>> aZeroMotionCluster;
579 for (
size_t j = 0; j < aPixelsAndFlowDirections.size(); j++)
581 float fAbsMotion = fabs(aPixelsAndFlowDirections.at(j).at(2)) +
582 fabs(aPixelsAndFlowDirections.at(j).at(3));
584 if (fAbsMotion < 350)
586 aZeroMotionCluster.push_back(aPixelsAndFlowDirections.at(j));
587 aPixelsAndFlowDirections.at(j) =
588 aPixelsAndFlowDirections.at(aPixelsAndFlowDirections.size() - 1);
589 aPixelsAndFlowDirections.pop_back();
594 std::vector<std::vector<int>> aOldIndices;
595 const float fBIC = 0.08;
596 clusterXMeans(aPixelsAndFlowDirections,
598 maxNumOptFlowClusters,
603 opticalFlowClusters.push_back(aZeroMotionCluster);
608 ::ImageProcessor::CopyImage(camImgLeftGreySmall, camImgLeftGreyOldSmall);
612 VisualContactDetection::detectCollision()
620 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
621 ->getRobotNode(handFrameName)
622 ->getPoseInRootFrame())
624 Vec3d handPosSensor = {handNodePose(0, 3), handNodePose(1, 3), handNodePose(2, 3)};
628 Math3d::SetVec(oldHandPosSensor, handPosSensor);
632 Vec3d pushDirection, pushDirectionNormalized;
634 Math3d::SubtractVecVec(handPosSensor, oldHandPosSensor, pushDirection);
635 Math3d::SetVec(pushDirectionNormalized, pushDirection);
637 ARMARX_INFO <<
"Push direction: " << pushDirection.x <<
" " << pushDirection.y <<
" "
640 if (Math3d::Length(pushDirection) > 0)
642 Math3d::NormalizeVec(pushDirectionNormalized);
643 Math3d::MulVecScalar(pushDirection,
644 pushDetectionBoxForwardOffsetToTCP / Math3d::Length(pushDirection),
649 Eigen::Vector3f forwardAxis;
650 forwardAxis << 0.0f, 1.0f, 1.0f;
651 forwardAxis.normalize();
652 forwardAxis = handNodePose.block<3, 3>(0, 0) * forwardAxis;
653 Vec3d forwardDirection = {forwardAxis(0), forwardAxis(1), forwardAxis(2)};
655 << Math3d::ScalarProduct(forwardDirection, pushDirectionNormalized);
661 if ((Math3d::ScalarProduct(forwardDirection, pushDirectionNormalized) < -0.6f) ||
662 (Math3d::Length(pushDirection) == 0))
664 ARMARX_INFO <<
"Not checking for collision because arm is not moving forward";
672 Eigen::Vector3f pushDirectionForBox = {pushDirection.x, pushDirection.y, pushDirection.z};
673 forwardAxis *= 1.0f * pushDetectionBoxForwardOffsetToTCP;
674 pushDirectionForBox = 0.5f * (pushDirectionForBox + forwardAxis);
676 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
677 ->getRobotNode(cameraFrameName)
678 ->getPoseInRootFrame())
680 Eigen::Vector3f pushDirectionInCameraCoords =
681 cameraNodePose.block<3, 3>(0, 0) * pushDirectionForBox;
683 Vec3d handPosPF = {handPosePF(0, 3), handPosePF(1, 3), handPosePF(2, 3)};
684 Vec3d pushTarget = {handPosPF.x + pushDirectionInCameraCoords(0),
685 handPosPF.y + pushDirectionInCameraCoords(1),
686 handPosPF.z + pushDirectionInCameraCoords(2)};
688 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
689 handPosPF, handPos2D,
false);
690 stereoCalibration->GetLeftCalibration()->WorldToImageCoordinates(
691 pushTarget, pushTarget2D,
false);
693 const float handCameraDistance =
694 (handNodePose.block<3, 1>(0, 3) - cameraNodePose.block<3, 1>(0, 3)).
norm();
695 const float boxSize = 80.0f;
696 Vec2d pushTargetBoxSize = {boxSize * 600 / handCameraDistance,
697 boxSize * 600 / handCameraDistance};
698 ARMARX_INFO <<
"pushTargetBoxSize: " << pushTargetBoxSize.x;
700 Math2d::SetVec(pushTargetBoxLeftUpperCorner,
701 pushTarget2D.x - pushTargetBoxSize.x,
702 pushTarget2D.y - pushTargetBoxSize.y);
703 Math2d::SetVec(pushTargetBoxRightLowerCorner,
704 pushTarget2D.x + pushTargetBoxSize.x,
705 pushTarget2D.y + pushTargetBoxSize.y);
707 if (pushTargetBoxLeftUpperCorner.x < 0)
709 pushTargetBoxLeftUpperCorner.x = 0;
712 if (pushTargetBoxLeftUpperCorner.y < 0)
714 pushTargetBoxLeftUpperCorner.y = 0;
727 Math3d::SetVec(oldHandPosSensor, handPosSensor);
736 bool bContact =
false;
738 std::vector<int> aNumClusterPointsInPushingBox, aNumClusterPointsInHandArea,
739 aNumClusterPointsInRestOfImage;
741 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
743 aNumClusterPointsInPushingBox.push_back(0);
744 aNumClusterPointsInHandArea.push_back(0);
745 aNumClusterPointsInRestOfImage.push_back(0);
748 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
750 for (
size_t k = 0; k < opticalFlowClusters.at(j).size(); k++)
752 const float y = opticalFlowClusters.at(j).at(k).at(0);
753 const float x = opticalFlowClusters.at(j).at(k).at(1);
758 if (pSegmentedImage->pixels[3 * nIndex])
760 aNumClusterPointsInHandArea.at(j)++;
762 else if (pushTargetBoxLeftUpperCorner.x <= x &&
763 x <= pushTargetBoxRightLowerCorner.x &&
764 pushTargetBoxLeftUpperCorner.y <= y &&
765 y <= pushTargetBoxRightLowerCorner.y)
767 aNumClusterPointsInPushingBox.at(j)++;
771 aNumClusterPointsInRestOfImage.at(j)++;
776 aNumClusterPointsInRestOfImage.at(j)++;
781 float fBestRatio = 0;
784 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
786 if (aNumClusterPointsInPushingBox.at(j) > minNumPixelsInClusterForCollisionDetection)
788 float fRatio = (
float)aNumClusterPointsInPushingBox.at(j) /
789 (
float)(aNumClusterPointsInPushingBox.at(j) +
790 aNumClusterPointsInRestOfImage.at(j));
792 if (fRatio > fBestRatio)
800 ARMARX_LOG <<
"Contact probability: " << fBestRatio;
802 bContact = (fBestRatio > 0.5f && oldCollisionProbability > 0.5);
803 oldCollisionProbability = fBestRatio;
809 << clusteringSampleStep * clusteringSampleStep *
810 imageResizeFactorForOpticalFlowCalculation *
811 imageResizeFactorForOpticalFlowCalculation *
812 aNumClusterPointsInPushingBox.at(nBestIndex);
819 VisualContactDetection::drawVisualization(
bool collisionDetected)
821 timesOfImageCapture.push_back(IceUtil::Time::now().toMilliSeconds());
823 #pragma omp parallel sections
830 CByteImage* pNew =
new CByteImage(cameraImages[0]);
831 ::ImageProcessor::CopyImage(cameraImages[0], pNew);
832 cameraImagesForSaving.push_back(pNew);
843 drawComplexHandModelInResultImage);
844 delete[] sensorConfig;
845 ::ImageProcessor::CopyImage(cameraImages[0], tempImageRGB1);
848 for (
int i = 0; i < cameraImages[0]->height; i++)
850 for (
int j = 0; j < cameraImages[0]->width; j++)
852 resultImages[eEverything]
853 ->pixels[3 * (i * 3 * cameraImages[0]->width + j)] =
854 tempImageRGB1->pixels[3 * (i * cameraImages[0]->width + j)];
855 resultImages[eEverything]
856 ->pixels[3 * (i * 3 * cameraImages[0]->width + j) + 1] =
857 tempImageRGB1->pixels[3 * (i * cameraImages[0]->width + j) + 1];
858 resultImages[eEverything]
859 ->pixels[3 * (i * 3 * cameraImages[0]->width + j) + 2] =
860 tempImageRGB1->pixels[3 * (i * cameraImages[0]->width + j) + 2];
870 drawComplexHandModelInResultImage);
871 delete[] localizationResult;
872 ::ImageProcessor::CopyImage(cameraImages[0], tempImageRGB2);
875 for (
int i = 0; i < cameraImages[0]->height; i++)
877 for (
int j = 0, j2 = cameraImages[0]->width; j < cameraImages[0]->width;
880 resultImages[eEverything]
881 ->pixels[3 * (i * 3 * cameraImages[0]->width + j2)] =
882 tempImageRGB2->pixels[3 * (i * cameraImages[0]->width + j)];
883 resultImages[eEverything]
884 ->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 1] =
885 tempImageRGB2->pixels[3 * (i * cameraImages[0]->width + j) + 1];
886 resultImages[eEverything]
887 ->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 2] =
888 tempImageRGB2->pixels[3 * (i * cameraImages[0]->width + j) + 2];
894 CByteImage* pNew =
new CByteImage(tempImageRGB2);
895 ::ImageProcessor::CopyImage(tempImageRGB2, pNew);
896 localizationResultImages.push_back(pNew);
905 drawComplexHandModelInResultImage);
906 delete[] localizationResult;
907 ::ImageProcessor::CopyImage(cameraImages[1], tempImageRGB3);
910 for (
int i = 0; i < cameraImages[0]->height; i++)
912 for (
int j = 0, j2 = 2 * cameraImages[0]->width; j < cameraImages[0]->width;
915 resultImages[eEverything]
916 ->pixels[3 * (i * 3 * cameraImages[0]->width + j2)] =
917 tempImageRGB3->pixels[3 * (i * cameraImages[0]->width + j)];
918 resultImages[eEverything]
919 ->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 1] =
920 tempImageRGB3->pixels[3 * (i * cameraImages[0]->width + j) + 1];
921 resultImages[eEverything]
922 ->pixels[3 * (i * 3 * cameraImages[0]->width + j2) + 2] =
923 tempImageRGB3->pixels[3 * (i * cameraImages[0]->width + j) + 2];
931 for (
int i = 0, i2 = cameraImages[0]->height; i < cameraImages[0]->height;
934 for (
int j = 0; j < cameraImages[0]->width; j++)
936 resultImages[eEverything]
937 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j)] =
938 pSegmentedImage->pixels[3 * (i * cameraImages[0]->width + j)];
939 resultImages[eEverything]
940 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j) + 1] =
941 pSegmentedImage->pixels[3 * (i * cameraImages[0]->width + j) + 1];
942 resultImages[eEverything]
943 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j) + 2] =
944 pSegmentedImage->pixels[3 * (i * cameraImages[0]->width + j) + 2];
954 ::ImageProcessor::Zero(tempImageRGB4);
969 int nValue = 255 * pVisOptFlowRaw[j];
971 tempImageRGB4->pixels[j] = (0 > nValue) ? 0 : ((255 < nValue) ? 255 : nValue);
974 for (
int i = 0, i2 = cameraImages[0]->height; i < cameraImages[0]->height;
977 for (
int j = 0, j2 = cameraImages[0]->width; j < cameraImages[0]->width;
980 resultImages[eEverything]
981 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2)] =
982 tempImageRGB4->pixels[3 * (i * cameraImages[0]->width + j)];
983 resultImages[eEverything]
984 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 1] =
985 tempImageRGB4->pixels[3 * (i * cameraImages[0]->width + j) + 1];
986 resultImages[eEverything]
987 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 2] =
988 tempImageRGB4->pixels[3 * (i * cameraImages[0]->width + j) + 2];
994 CByteImage* pNew =
new CByteImage(tempImageRGB4);
995 ::ImageProcessor::CopyImage(tempImageRGB4, pNew);
996 opticalFlowImages.push_back(pNew);
1003 ::ImageProcessor::Zero(pOpticalFlowClusterImage);
1005 for (
size_t j = 0; j < opticalFlowClusters.size(); j++)
1007 ARMARX_VERBOSE_S <<
"Cluster " << j <<
": " << opticalFlowClusters.at(j).size()
1010 for (
size_t k = 0; k < opticalFlowClusters.at(j).size(); k++)
1013 opticalFlowClusters.at(j).at(k).at(1);
1017 for (
int l = 0; l < imageResizeFactorForOpticalFlowCalculation *
1018 clusteringSampleStep;
1021 for (
int m = 0; m < imageResizeFactorForOpticalFlowCalculation *
1022 clusteringSampleStep;
1029 pOpticalFlowClusterImage->pixels[3 * nIndex2] =
1031 pOpticalFlowClusterImage->pixels[3 * nIndex2 + 1] =
1033 pOpticalFlowClusterImage->pixels[3 * nIndex2 + 2] =
1044 if (handPos2D.x != -1 || handPos2D.y != -1)
1048 if (pSegmentedImage->pixels[j])
1050 pOpticalFlowClusterImage->pixels[j] /= 2;
1055 pOpticalFlowClusterImage, handPos2D.x, handPos2D.y, 255, 255, 255);
1056 int n = collisionDetected ? 8 : 2;
1058 for (
int i = 0; i < n; i++)
1061 pushTargetBoxLeftUpperCorner.x + i,
1062 pushTargetBoxLeftUpperCorner.y + i,
1063 pushTargetBoxRightLowerCorner.x - i,
1064 pushTargetBoxLeftUpperCorner.y + i,
1069 pushTargetBoxRightLowerCorner.x - i,
1070 pushTargetBoxLeftUpperCorner.y + 1,
1071 pushTargetBoxRightLowerCorner.x - i,
1072 pushTargetBoxRightLowerCorner.y - i,
1077 pushTargetBoxRightLowerCorner.x - i,
1078 pushTargetBoxRightLowerCorner.y - i,
1079 pushTargetBoxLeftUpperCorner.x + i,
1080 pushTargetBoxRightLowerCorner.y - i,
1085 pushTargetBoxLeftUpperCorner.x + i,
1086 pushTargetBoxRightLowerCorner.y - i,
1087 pushTargetBoxLeftUpperCorner.x + i,
1088 pushTargetBoxLeftUpperCorner.y + i,
1094 for (
int i = 0, i2 = cameraImages[0]->height; i < cameraImages[0]->height;
1097 for (
int j = 0, j2 = 2 * cameraImages[0]->width; j < cameraImages[0]->width;
1100 resultImages[eEverything]
1101 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2)] =
1102 pOpticalFlowClusterImage
1103 ->pixels[3 * (i * cameraImages[0]->width + j)];
1104 resultImages[eEverything]
1105 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 1] =
1106 pOpticalFlowClusterImage
1107 ->pixels[3 * (i * cameraImages[0]->width + j) + 1];
1108 resultImages[eEverything]
1109 ->pixels[3 * (i2 * 3 * cameraImages[0]->width + j2) + 2] =
1110 pOpticalFlowClusterImage
1111 ->pixels[3 * (i * cameraImages[0]->width + j) + 2];
1118 CByteImage* pNew =
new CByteImage(pOpticalFlowClusterImage);
1119 ::ImageProcessor::CopyImage(pOpticalFlowClusterImage, pNew);
1120 opticalFlowClusterImages.push_back(pNew);
1129 delete[] cameraImages;
1133 ARMARX_INFO <<
"Writing all visualization images to disk...";
1134 std::string path =
"/localhome/ottenhau/VisColDet/";
1135 std::string fileNameCam = path +
"cam0000.bmp";
1136 std::string fileNameLocRes = path +
"locres0000.bmp";
1137 std::string fileNameOptFlow = path +
"optflow0000.bmp";
1138 std::string fileNameOptFlowClus = path +
"optflowclus0000.bmp";
1139 std::string fileNameTimes = path +
"times.txt";
1140 FILE* pFile = fopen(fileNameTimes.c_str(),
"wt");
1141 fprintf(pFile,
"%ld \n", timesOfImageCapture.size() - 1);
1143 for (
long i = 0; i < (long)timesOfImageCapture.size() - 1; i++)
1145 fprintf(pFile,
"%ld %ld \n", i, timesOfImageCapture.at(i));
1146 SetNumberInFileName(fileNameCam, i, 4);
1147 SetNumberInFileName(fileNameLocRes, i, 4);
1148 SetNumberInFileName(fileNameOptFlow, i, 4);
1149 SetNumberInFileName(fileNameOptFlowClus, i, 4);
1150 cameraImagesForSaving.at(i)->SaveToFile(fileNameCam.c_str());
1151 localizationResultImages.at(i)->SaveToFile(fileNameLocRes.c_str());
1152 opticalFlowImages.at(i)->SaveToFile(fileNameOptFlow.c_str());
1153 opticalFlowClusterImages.at(i)->SaveToFile(fileNameOptFlowClus.c_str());
1154 delete cameraImagesForSaving.at(i);
1155 delete localizationResultImages.at(i);
1156 delete opticalFlowImages.at(i);
1157 delete opticalFlowClusterImages.at(i);
1161 ARMARX_VERBOSE <<
"Image " << i <<
" of " << timesOfImageCapture.size();
1166 ARMARX_INFO <<
"Finished writing all visualization images to disk";
1171 VisualContactDetection::extractAnglesFromRotationMatrix(
const Mat3d& mat,
Vec3d& angles)
1173 angles.y = asin(mat.r3);
1174 angles.x = atan2((-mat.r6), (mat.r9));
1175 angles.z = atan2((-mat.r2), (mat.r1));
1179 VisualContactDetection::convertToIplImage(CByteImage* pByteImageRGB)
1181 if (pByteImageRGB->type == CByteImage::eRGB24)
1183 unsigned char cTemp;
1185 for (
int j = 0; j < pByteImageRGB->width * pByteImageRGB->height; j++)
1187 cTemp = pByteImageRGB->pixels[3 * j];
1188 pByteImageRGB->pixels[3 * j] = pByteImageRGB->pixels[3 * j + 2];
1189 pByteImageRGB->pixels[3 * j + 2] = cTemp;
1193 IplImage* pRet = IplImageAdaptor::Adapt(pByteImageRGB);
1198 VisualContactDetection::clusterXMeans(
1199 const std::vector<std::vector<float>>& aPoints,
1200 const int nMinNumClusters,
1201 const int nMaxNumClusters,
1202 const float fBICFactor,
1203 std::vector<std::vector<std::vector<float>>>& aaPointClusters,
1204 std::vector<std::vector<int>>& aaOldIndices)
1206 aaPointClusters.clear();
1207 aaOldIndices.clear();
1208 const int nNumberOfSamples = aPoints.size();
1210 if (nNumberOfSamples < nMaxNumClusters)
1221 const int nNumberOfDifferentInitialisations = 4;
1222 cv::TermCriteria tTerminationCriteria(
1226 const int nDimension = aPoints.at(0).size();
1227 mSamples.create(nNumberOfSamples, nDimension, CV_32FC1);
1229 for (
int i = 0; i < nNumberOfSamples; i++)
1231 for (
int j = 0; j < nDimension; j++)
1233 mSamples.at<
float>(i, j) = aPoints.at(i).at(j);
1237 std::vector<std::vector<std::vector<float>>>* aaPointClustersForAllK =
1238 new std::vector<std::vector<std::vector<float>>>[nMaxNumClusters + 1];
1239 std::vector<std::vector<int>>* aaOldIndicesForAllK =
1240 new std::vector<std::vector<int>>[nMaxNumClusters + 1];
1245 double dMinBIC = 10000000;
1246 int nOptK = nMinNumClusters;
1248 #pragma omp parallel for schedule(dynamic, 1)
1249 for (
int k = nMaxNumClusters; k >= nMinNumClusters; k--)
1251 double dKMeansCompactness, dLogVar, dBIC;
1252 cv::Mat mClusterLabelsLocal;
1253 mClusterLabelsLocal.create(nNumberOfSamples, 1, CV_32SC1);
1254 cv::Mat mClusterCentersLocal;
1255 dKMeansCompactness = cv::kmeans(mSamples,
1257 mClusterLabelsLocal,
1258 tTerminationCriteria,
1259 nNumberOfDifferentInitialisations,
1260 cv::KMEANS_RANDOM_CENTERS,
1261 mClusterCentersLocal);
1263 const int nNumberOfFreeParameters = (k - 1) + (nDimension * k) + k;
1264 dLogVar = log(dKMeansCompactness);
1265 dBIC = fBICFactor * 0.35 * dLogVar +
1266 ((double)nNumberOfFreeParameters / (
double)nNumberOfSamples) *
1267 log((
double)nNumberOfSamples);
1269 #pragma omp critical
1276 if (dBIC == dMinBIC)
1278 std::vector<float> vPoint;
1279 vPoint.resize(nDimension);
1281 for (
int i = 0; i < k; i++)
1283 std::vector<std::vector<float>> aNewCluster;
1284 aaPointClustersForAllK[k].push_back(aNewCluster);
1285 std::vector<int> aClusterIndices;
1286 aaOldIndicesForAllK[k].push_back(aClusterIndices);
1289 for (
int i = 0; i < nNumberOfSamples; i++)
1291 const int nLabel = mClusterLabelsLocal.at<
int>(i, 0);
1293 if ((nLabel >= 0) && (nLabel < k))
1295 for (
int j = 0; j < nDimension; j++)
1297 vPoint.at(j) = mSamples.at<
float>(i, j);
1300 aaPointClustersForAllK[k].at(nLabel).push_back(vPoint);
1301 aaOldIndicesForAllK[k].at(nLabel).push_back(i);
1316 aaPointClusters = aaPointClustersForAllK[nOptK];
1317 aaOldIndices = aaOldIndicesForAllK[nOptK];
1319 delete[] aaPointClustersForAllK;
1320 delete[] aaOldIndicesForAllK;
1323 armarx::FramedPoseBasePtr
1328 handPose, cameraFrameName, robotStateProxy->getSynchronizedRobot()->getName());
1332 visionx::FramedPositionBaseList
1335 visionx::FramedPositionBaseList
ret;
1338 for (
size_t i = 0; i < fingertipPositions.size(); i++)
1340 Eigen::Vector3f position;
1341 position << fingertipPositions.at(i).x, fingertipPositions.at(i).y,
1342 fingertipPositions.at(i).z;
1344 position, cameraFrameName, robotStateProxy->getSynchronizedRobot()->getName());
1354 std::unique_lock lock(activationStateMutex);
1363 int nNumberImages =
getImages(cameraImages);
1365 ::ImageProcessor::ConvertImage(cameraImages[0], camImgLeftGrey);
1366 ::ImageProcessor::Resize(camImgLeftGrey, camImgLeftGreyOldSmall);
1369 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
1370 ->getRobotNode(handFrameName)
1371 ->getPoseInRootFrame())
1374 oldHandPosSensor, handNodePose(0, 3), handNodePose(1, 3), handNodePose(2, 3));
1377 timeOfLastExecution = IceUtil::Time::now();
1378 oldCollisionProbability = 0;
1385 std::unique_lock lock(activationStateMutex);
1390 VisualContactDetection::SetNumberInFileName(std::string& sFileName,
int nNumber,
int nNumDigits)
1392 for (
int i = 0; i < nNumDigits; i++)
1394 int nDecimalDivisor = 1;
1396 for (
int j = 0; j < i; j++)
1398 nDecimalDivisor *= 10;
1401 sFileName.at(sFileName.length() - (5 + i)) =
'0' + (nNumber / nDecimalDivisor) % 10;