33 #include <Image/ByteImage.h>
34 #include <DataProcessing/RANSAC.h>
35 #include <SegmentableRecognition/SegmentableDatabase.h>
36 #include <Image/ImageProcessor.h>
37 #include <Math/Math3d.h>
45 #include <gui/GLContext.h>
53 ColorMarkerObjectLocalizer::ColorMarkerObjectLocalizer()
57 ColorMarkerObjectLocalizer::~ColorMarkerObjectLocalizer()
62 void ColorMarkerObjectLocalizer::onInitObjectLocalizerProcessor()
64 usingProxy(
"RobotStateComponent");
67 void ColorMarkerObjectLocalizer::onConnectObjectLocalizerProcessor()
70 remoteRobot.reset(
new RemoteRobot(robotStateComponent->getSynchronizedRobot()));
73 void ColorMarkerObjectLocalizer::onExitObjectLocalizerProcessor()
78 bool ColorMarkerObjectLocalizer::initRecognizer()
82 minPixelsPerRegion = getProperty<float>(
"MinPixelsPerRegion").getValue();
83 numObjectMarker = getProperty<int>(
"NumObjectMarker").getValue();
84 markeredObjectName = getProperty<std::string>(
"MarkeredObjectName").getValue();
85 maxEpipolarDistance = getProperty<float>(
"MaxEpipolarDistance").getValue();
87 hue = getProperty<int>(
"Hue").getValue();
88 hueTol = getProperty<int>(
"HueTolerance").getValue();
89 minS = getProperty<int>(
"MinSaturation").getValue();
90 maxS = getProperty<int>(
"MaxSaturation").getValue();
91 minV = getProperty<int>(
"MinValue").getValue();
92 maxV = getProperty<int>(
"MaxValue").getValue();
93 objectMarkerColor = CColorParameterSet::Translate(getProperty<std::string>(
"MarkerColor").getValue().c_str());
96 if (!segmentableRecognition)
98 colorParameters.reset(
new CColorParameterSet());
100 colorParameters->SetColorParameters(objectMarkerColor, hue, hueTol, minS, maxS, minV, maxV);
104 segmentableRecognition.reset(
new CSegmentableRecognition());
109 ImageFormatInfo imageFormat = getImageFormat();
110 contextGL.reset(
new CGLContext());
114 contextGL->CreateContext(imageFormat.dimension.width, imageFormat.dimension.height);
118 contextGL->MakeCurrent();
120 m_pOpenGLVisualizer.reset(
new COpenGLVisualizer());
121 m_pOpenGLVisualizer->InitByCalibration(getStereoCalibration()->GetRightCalibration());
126 bool success = segmentableRecognition->InitWithoutDatabase(colorParameters.get(), getStereoCalibration());
130 throw armarx::LocalException(
"Could not initialize segmentable object database.");
145 memoryx::ObjectLocalizationResultList ColorMarkerObjectLocalizer::localizeObjectClasses(
const std::vector<std::string>& objectClassNames, CByteImage** cameraImages, armarx::MetaInfoSizeBasePtr imageMetaInfo, CByteImage** resultImages)
148 contextGL->MakeCurrent();
150 Object3DList objectList;
154 segmentableRecognition->DoRecognition(cameraImages, resultImages, minPixelsPerRegion,
true, maxEpipolarDistance, objectMarkerColor,
false, getImagesAreUndistorted());
156 objectList = segmentableRecognition->GetObject3DList();
158 ARMARX_INFO <<
"Found " << objectList.size() <<
" objects";
160 memoryx::ObjectLocalizationResultList resultList;
162 visualizeResults(objectList, resultImages);
163 std::string refFrame = getProperty<std::string>(
"ReferenceFrameName").getValue();
164 std::string camFrame(
"EyeLeftCamera");
166 Eigen::Vector3f objectPosition(0.0, 0.0, 0.0);
168 bool bChairLocalized =
false;
170 if (objectList.size() == numObjectMarker)
174 CVec3dArray allMarkerPositions;
177 for (Object3DList::iterator iter = objectList.begin() ; iter != objectList.end() ; iter++)
187 std::cout << iter->world_point.x <<
" " << iter->world_point.y <<
" " << iter->world_point.z << std::endl;
188 std::cout << iter->pose.translation.x <<
" " << iter->pose.translation.y <<
" " << iter->pose.translation.z << std::endl;
189 Eigen::Vector3f markerPosition(iter->pose.translation.x, iter->pose.translation.y, iter->pose.translation.z);
190 objectPosition += markerPosition;
191 Vec3d singleMarkerPosition;
192 singleMarkerPosition.x = markerPosition(0);
193 singleMarkerPosition.y = markerPosition(1);
194 singleMarkerPosition.z = markerPosition(2);
195 allMarkerPositions.AddElement(singleMarkerPosition);
200 objectPosition /= numObjectMarker;
202 std::vector<int> markerPlacementIndex(numObjectMarker);
203 float min1Distance = 0;
205 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
209 for (
int j = 0; j < allMarkerPositions.GetSize(); j++)
211 float temp1Distance = 0;
218 temp1Distance += (allMarkerPositions[i].x - allMarkerPositions[j].x) * (allMarkerPositions[i].x - allMarkerPositions[j].x);
219 temp1Distance += (allMarkerPositions[i].y - allMarkerPositions[j].y) * (allMarkerPositions[i].y - allMarkerPositions[j].y);
220 temp1Distance += (allMarkerPositions[i].z - allMarkerPositions[j].z) * (allMarkerPositions[i].z - allMarkerPositions[j].z);
221 temp1Distance =
sqrt(temp1Distance);
223 if (min1Distance == 0 || temp1Distance < min1Distance)
225 std::cout <<
"minDist " << min1Distance << std::endl;
226 min1Distance = temp1Distance;
228 for (
int k = 0; k < allMarkerPositions.GetSize(); k++)
230 markerPlacementIndex[k] = 0;
233 markerPlacementIndex[i] = 1;
234 markerPlacementIndex[j] = 1;
241 Vec3d minMeanPosition;
242 minMeanPosition.x = 0.0;
243 minMeanPosition.y = 0.0;
244 minMeanPosition.z = 0.0;
246 Vec3d otherMeanPosition;
247 otherMeanPosition.x = 0.0;
248 otherMeanPosition.y = 0.0;
249 otherMeanPosition.z = 0.0;
251 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
253 std::cout << markerPlacementIndex[i] <<
" ";
255 if (markerPlacementIndex[i] == 1)
257 minMeanPosition.x += allMarkerPositions[i].x;
258 minMeanPosition.y += allMarkerPositions[i].y;
259 minMeanPosition.z += allMarkerPositions[i].z;
263 otherMeanPosition.x += allMarkerPositions[i].x;
264 otherMeanPosition.y += allMarkerPositions[i].y;
265 otherMeanPosition.z += allMarkerPositions[i].z;
269 std::cout << std::endl;
270 minMeanPosition.x /= 2.0;
271 minMeanPosition.y /= 2.0;
272 minMeanPosition.z /= 2.0;
273 otherMeanPosition.x /=
float(numObjectMarker - 2);
274 otherMeanPosition.y /=
float(numObjectMarker - 2);
275 otherMeanPosition.z /=
float(numObjectMarker - 2);
276 std::cout <<
"minMean " << minMeanPosition.x <<
" " << minMeanPosition.y <<
" " << minMeanPosition.z << std::endl;
277 std::cout <<
"oterhMean " << otherMeanPosition.x <<
" " << otherMeanPosition.y <<
" " << otherMeanPosition.z << std::endl;
283 ny.x = minMeanPosition.x - otherMeanPosition.x;
284 ny.z = minMeanPosition.z - otherMeanPosition.z;
294 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
296 Math3d::NormalizeVec(ny);
297 Math3d::CrossProduct(ny, nz, nx);
298 std::cout <<
"objectPosition" << std::endl;
299 std::cout << objectPosition << std::endl;
300 objectOrientation << nx.x, ny.x, nz.x, nx.y, ny.y, nz.y, nx.z, ny.z, nz.z;
301 std::cout <<
"objectOrientation" << std::endl;
302 std::cout << objectOrientation << std::endl;
303 cPositionNoise = calculateLocalizationUncertainty(objectList[0].region_left.centroid, objectList[0].region_right.centroid);;
304 bChairLocalized =
true;
305 ARMARX_VERBOSE <<
"Finished localizing " << markeredObjectName <<
" in " << refFrame;
307 else if (objectList.size() == numObjectMarker - 1)
312 CVec3dArray allMarkerPositions;
314 for (Object3DList::iterator iter = objectList.begin() ; iter != objectList.end() ; iter++)
324 std::cout << iter->world_point.x <<
" " << iter->world_point.y <<
" " << iter->world_point.z << std::endl;
325 std::cout << iter->pose.translation.x <<
" " << iter->pose.translation.y <<
" " << iter->pose.translation.z << std::endl;
326 Eigen::Vector3f markerPosition(iter->pose.translation.x, iter->pose.translation.y, iter->pose.translation.z);
327 objectPosition += markerPosition;
328 Vec3d singleMarkerPosition;
329 singleMarkerPosition.x = markerPosition(0);
330 singleMarkerPosition.y = markerPosition(1);
331 singleMarkerPosition.z = markerPosition(2);
332 allMarkerPositions.AddElement(singleMarkerPosition);
337 objectPosition /= numObjectMarker;
340 Vec3d u1, u2, ny, nz, nx, zAxis;
341 Math3d::SubtractVecVec(allMarkerPositions[1], allMarkerPositions[0], u1);
342 Math3d::SubtractVecVec(allMarkerPositions[2], allMarkerPositions[0], u2);
343 Math3d::CrossProduct(u1, u2, ny);
348 if (Math3d::Angle(zAxis, ny) <
M_PI)
363 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
365 Math3d::NormalizeVec(ny);
366 Math3d::CrossProduct(ny, nz, nx);
367 std::cout <<
"objectPosition" << std::endl;
368 std::cout << objectPosition << std::endl;
369 objectOrientation << nx.x, ny.x, nz.x, nx.y, ny.y, nz.y, nx.z, ny.z, nz.z;
370 std::cout <<
"objectOrientation" << std::endl;
371 std::cout << objectOrientation << std::endl;
372 cPositionNoise = calculateLocalizationUncertainty(objectList[0].region_left.centroid, objectList[0].region_right.centroid);;
373 bChairLocalized =
true;
374 ARMARX_VERBOSE <<
"Finished localizing " << markeredObjectName <<
" in " << refFrame;
376 else if (objectList.size() == numObjectMarker + 1)
381 CVec3dArray allMarkerPositions;
383 for (Object3DList::iterator iter = objectList.begin() ; iter != objectList.end() ; iter++)
393 std::cout << iter->world_point.x <<
" " << iter->world_point.y <<
" " << iter->world_point.z << std::endl;
394 std::cout << iter->pose.translation.x <<
" " << iter->pose.translation.y <<
" " << iter->pose.translation.z << std::endl;
395 Eigen::Vector3f markerPosition(iter->pose.translation.x, iter->pose.translation.y, iter->pose.translation.z);
396 objectPosition += markerPosition;
397 Vec3d singleMarkerPosition;
398 singleMarkerPosition.x = markerPosition(0);
399 singleMarkerPosition.y = markerPosition(1);
400 singleMarkerPosition.z = markerPosition(2);
401 allMarkerPositions.AddElement(singleMarkerPosition);
406 objectPosition /= numObjectMarker;
408 std::vector<int> markerPlacementIndex(numObjectMarker);
409 float min1Distance = 0;
411 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
415 for (
int j = 0; j < allMarkerPositions.GetSize(); j++)
417 float temp1Distance = 0;
424 temp1Distance += (allMarkerPositions[i].x - allMarkerPositions[j].x) * (allMarkerPositions[i].x - allMarkerPositions[j].x);
425 temp1Distance += (allMarkerPositions[i].y - allMarkerPositions[j].y) * (allMarkerPositions[i].y - allMarkerPositions[j].y);
426 temp1Distance += (allMarkerPositions[i].z - allMarkerPositions[j].z) * (allMarkerPositions[i].z - allMarkerPositions[j].z);
427 temp1Distance =
sqrt(temp1Distance);
429 if (min1Distance == 0 || temp1Distance < min1Distance)
431 std::cout <<
"minDist " << min1Distance << std::endl;
432 min1Distance = temp1Distance;
434 for (
int k = 0; k < allMarkerPositions.GetSize(); k++)
436 markerPlacementIndex[k] = 0;
439 markerPlacementIndex[i] = 1;
440 markerPlacementIndex[j] = 1;
447 Vec3d minMeanPosition;
448 minMeanPosition.x = 0.0;
449 minMeanPosition.y = 0.0;
450 minMeanPosition.z = 0.0;
451 CVec3dArray otherMarkerPositions;
452 Vec3d otherMeanPosition;
453 otherMeanPosition.x = 0.0;
454 otherMeanPosition.y = 0.0;
455 otherMeanPosition.z = 0.0;
457 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
459 std::cout << markerPlacementIndex[i] <<
" ";
461 if (markerPlacementIndex[i] == 1)
463 minMeanPosition.x += allMarkerPositions[i].x;
464 minMeanPosition.y += allMarkerPositions[i].y;
465 minMeanPosition.z += allMarkerPositions[i].z;
469 otherMarkerPositions.AddElement(allMarkerPositions[i]);
473 std::cout << std::endl;
474 minMeanPosition.x /= 2.0;
475 minMeanPosition.y /= 2.0;
476 minMeanPosition.z /= 2.0;
477 otherMeanPosition.x /=
float(numObjectMarker - 2);
478 otherMeanPosition.y /=
float(numObjectMarker - 2);
479 otherMeanPosition.z /=
float(numObjectMarker - 2);
480 std::cout <<
"minMean " << minMeanPosition.x <<
" " << minMeanPosition.y <<
" " << minMeanPosition.z << std::endl;
481 std::cout <<
"oterhMean " << otherMeanPosition.x <<
" " << otherMeanPosition.y <<
" " << otherMeanPosition.z << std::endl;
482 Vec3d u1, u2, ny, nz, nx, zAxis;
483 Math3d::SubtractVecVec(otherMarkerPositions[1], otherMarkerPositions[0], u1);
484 Math3d::SubtractVecVec(otherMarkerPositions[2], otherMarkerPositions[0], u2);
485 Math3d::CrossProduct(u1, u2, ny);
489 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
491 if (Math3d::Angle(zAxis, ny) >
M_PI)
506 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
508 Math3d::NormalizeVec(ny);
509 Math3d::CrossProduct(ny, nz, nx);
510 std::cout <<
"objectPosition" << std::endl;
511 std::cout << objectPosition << std::endl;
512 objectOrientation << nx.x, ny.x, nz.x, nx.y, ny.y, nz.y, nx.z, ny.z, nz.z;
513 std::cout <<
"objectOrientation" << std::endl;
514 std::cout << objectOrientation << std::endl;
515 cPositionNoise = calculateLocalizationUncertainty(objectList[0].region_left.centroid, objectList[0].region_right.centroid);;
516 bChairLocalized =
true;
517 ARMARX_VERBOSE <<
"Finished localizing " << markeredObjectName <<
" in " << refFrame;
528 memoryx::ObjectLocalizationResult result;
529 VirtualRobot::RobotNodePtr rnBase = remoteRobot->getRobotNode(refFrame);
530 VirtualRobot::RobotNodePtr rnCam = remoteRobot->getRobotNode(camFrame);
531 auto agentName = remoteRobot->getName();
535 tmpPose->changeFrame(remoteRobot, refFrame);
536 Eigen::Vector3f zAxisChair(0.0, 0.0, 1.0);
537 Eigen::Vector3f yAxisChair((tmpPose->toEigen())(0, 1), (tmpPose->toEigen())(1, 1), (tmpPose->toEigen())(2, 1));
538 Eigen::Vector3f xAxisChair = yAxisChair.cross(zAxisChair);
539 yAxisChair = xAxisChair.cross(zAxisChair);
542 objectPoseCorrected(2, 3) = 50.0;
543 objectPoseCorrected(1, 3) += 400.0;
544 objectPoseCorrected.block(0, 0, 3, 1) = xAxisChair;
545 objectPoseCorrected.block(0, 2, 3, 1) = zAxisChair;
546 objectPoseCorrected.block(0, 1, 3, 1) = yAxisChair;
552 result.recognitionCertainty = 1.0;
554 result.objectClassName = markeredObjectName;
555 resultList.push_back(result);
563 void ColorMarkerObjectLocalizer::visualizeResults(
const Object3DList& objectList, CByteImage** resultImages)
565 m_pOpenGLVisualizer->ActivateShading(
true);
566 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
569 m_pOpenGLVisualizer->SetProjectionMatrix(getStereoCalibration()->GetRightCalibration());
571 m_pOpenGLVisualizer->Clear();
574 for (
int i = 0; i < (int) objectList.size(); i++)
576 const Object3DEntry& entry = objectList.at(i);
577 CSegmentableDatabase::DrawObjectFromFile(m_pOpenGLVisualizer.get(), entry.sOivFilePath.c_str(), entry.pose);
580 const int nImageIndex = 1;
582 if (resultImages && resultImages[nImageIndex])
584 CByteImage tempImage(resultImages[nImageIndex]);
585 m_pOpenGLVisualizer->GetImage(&tempImage);
586 ::ImageProcessor::FlipY(&tempImage, &tempImage);
587 const int nBytes = 3 * tempImage.width * tempImage.height;
588 const unsigned char* pixels = tempImage.pixels;
589 unsigned char* output = resultImages[nImageIndex]->pixels;
591 for (
int i = 0; i < nBytes; i += 3)
594 const unsigned char g = pixels[i];