33 #include <DataProcessing/RANSAC.h>
34 #include <Image/ByteImage.h>
35 #include <Image/ImageProcessor.h>
36 #include <Math/Math3d.h>
37 #include <SegmentableRecognition/SegmentableDatabase.h>
45 #include <gui/GLContext.h>
52 ColorMarkerObjectLocalizer::ColorMarkerObjectLocalizer()
56 ColorMarkerObjectLocalizer::~ColorMarkerObjectLocalizer()
61 ColorMarkerObjectLocalizer::onInitObjectLocalizerProcessor()
63 usingProxy(
"RobotStateComponent");
67 ColorMarkerObjectLocalizer::onConnectObjectLocalizerProcessor()
70 getProxy<RobotStateComponentInterfacePrx>(
"RobotStateComponent");
71 remoteRobot.reset(
new RemoteRobot(robotStateComponent->getSynchronizedRobot()));
75 ColorMarkerObjectLocalizer::onExitObjectLocalizerProcessor()
80 ColorMarkerObjectLocalizer::initRecognizer()
84 minPixelsPerRegion = getProperty<float>(
"MinPixelsPerRegion").getValue();
85 numObjectMarker = getProperty<int>(
"NumObjectMarker").getValue();
86 markeredObjectName = getProperty<std::string>(
"MarkeredObjectName").getValue();
87 maxEpipolarDistance = getProperty<float>(
"MaxEpipolarDistance").getValue();
89 hue = getProperty<int>(
"Hue").getValue();
90 hueTol = getProperty<int>(
"HueTolerance").getValue();
91 minS = getProperty<int>(
"MinSaturation").getValue();
92 maxS = getProperty<int>(
"MaxSaturation").getValue();
93 minV = getProperty<int>(
"MinValue").getValue();
94 maxV = getProperty<int>(
"MaxValue").getValue();
96 CColorParameterSet::Translate(getProperty<std::string>(
"MarkerColor").getValue().c_str());
99 if (!segmentableRecognition)
101 colorParameters.reset(
new CColorParameterSet());
103 colorParameters->SetColorParameters(objectMarkerColor, hue, hueTol, minS, maxS, minV, maxV);
107 segmentableRecognition.reset(
new CSegmentableRecognition());
112 ImageFormatInfo imageFormat = getImageFormat();
113 contextGL.reset(
new CGLContext());
117 contextGL->CreateContext(imageFormat.dimension.width, imageFormat.dimension.height);
121 contextGL->MakeCurrent();
123 m_pOpenGLVisualizer.reset(
new COpenGLVisualizer());
124 m_pOpenGLVisualizer->InitByCalibration(getStereoCalibration()->GetRightCalibration());
129 bool success = segmentableRecognition->InitWithoutDatabase(colorParameters.get(),
130 getStereoCalibration());
134 throw armarx::LocalException(
"Could not initialize segmentable object database.");
147 memoryx::ObjectLocalizationResultList
148 ColorMarkerObjectLocalizer::localizeObjectClasses(
const std::vector<std::string>& objectClassNames,
149 CByteImage** cameraImages,
150 armarx::MetaInfoSizeBasePtr imageMetaInfo,
151 CByteImage** resultImages)
154 contextGL->MakeCurrent();
156 Object3DList objectList;
160 segmentableRecognition->DoRecognition(cameraImages,
167 getImagesAreUndistorted());
169 objectList = segmentableRecognition->GetObject3DList();
171 ARMARX_INFO <<
"Found " << objectList.size() <<
" objects";
173 memoryx::ObjectLocalizationResultList resultList;
175 visualizeResults(objectList, resultImages);
176 std::string refFrame = getProperty<std::string>(
"ReferenceFrameName").getValue();
177 std::string camFrame(
"EyeLeftCamera");
179 Eigen::Vector3f objectPosition(0.0, 0.0, 0.0);
181 bool bChairLocalized =
false;
183 if (objectList.size() == numObjectMarker)
187 CVec3dArray allMarkerPositions;
190 for (Object3DList::iterator iter = objectList.begin(); iter != objectList.end(); iter++)
200 std::cout << iter->world_point.x <<
" " << iter->world_point.y <<
" "
201 << iter->world_point.z << std::endl;
202 std::cout << iter->pose.translation.x <<
" " << iter->pose.translation.y <<
" "
203 << iter->pose.translation.z << std::endl;
204 Eigen::Vector3f markerPosition(
205 iter->pose.translation.x, iter->pose.translation.y, iter->pose.translation.z);
206 objectPosition += markerPosition;
207 Vec3d singleMarkerPosition;
208 singleMarkerPosition.x = markerPosition(0);
209 singleMarkerPosition.y = markerPosition(1);
210 singleMarkerPosition.z = markerPosition(2);
211 allMarkerPositions.AddElement(singleMarkerPosition);
215 objectPosition /= numObjectMarker;
217 std::vector<int> markerPlacementIndex(numObjectMarker);
218 float min1Distance = 0;
220 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
224 for (
int j = 0; j < allMarkerPositions.GetSize(); j++)
226 float temp1Distance = 0;
233 temp1Distance += (allMarkerPositions[i].x - allMarkerPositions[j].x) *
234 (allMarkerPositions[i].x - allMarkerPositions[j].x);
235 temp1Distance += (allMarkerPositions[i].y - allMarkerPositions[j].y) *
236 (allMarkerPositions[i].y - allMarkerPositions[j].y);
237 temp1Distance += (allMarkerPositions[i].z - allMarkerPositions[j].z) *
238 (allMarkerPositions[i].z - allMarkerPositions[j].z);
239 temp1Distance =
sqrt(temp1Distance);
241 if (min1Distance == 0 || temp1Distance < min1Distance)
243 std::cout <<
"minDist " << min1Distance << std::endl;
244 min1Distance = temp1Distance;
246 for (
int k = 0; k < allMarkerPositions.GetSize(); k++)
248 markerPlacementIndex[k] = 0;
251 markerPlacementIndex[i] = 1;
252 markerPlacementIndex[j] = 1;
257 Vec3d minMeanPosition;
258 minMeanPosition.x = 0.0;
259 minMeanPosition.y = 0.0;
260 minMeanPosition.z = 0.0;
262 Vec3d otherMeanPosition;
263 otherMeanPosition.x = 0.0;
264 otherMeanPosition.y = 0.0;
265 otherMeanPosition.z = 0.0;
267 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
269 std::cout << markerPlacementIndex[i] <<
" ";
271 if (markerPlacementIndex[i] == 1)
273 minMeanPosition.x += allMarkerPositions[i].x;
274 minMeanPosition.y += allMarkerPositions[i].y;
275 minMeanPosition.z += allMarkerPositions[i].z;
279 otherMeanPosition.x += allMarkerPositions[i].x;
280 otherMeanPosition.y += allMarkerPositions[i].y;
281 otherMeanPosition.z += allMarkerPositions[i].z;
285 std::cout << std::endl;
286 minMeanPosition.x /= 2.0;
287 minMeanPosition.y /= 2.0;
288 minMeanPosition.z /= 2.0;
289 otherMeanPosition.x /=
float(numObjectMarker - 2);
290 otherMeanPosition.y /=
float(numObjectMarker - 2);
291 otherMeanPosition.z /=
float(numObjectMarker - 2);
292 std::cout <<
"minMean " << minMeanPosition.x <<
" " << minMeanPosition.y <<
" "
293 << minMeanPosition.z << std::endl;
294 std::cout <<
"oterhMean " << otherMeanPosition.x <<
" " << otherMeanPosition.y <<
" "
295 << otherMeanPosition.z << std::endl;
301 ny.x = minMeanPosition.x - otherMeanPosition.x;
302 ny.z = minMeanPosition.z - otherMeanPosition.z;
312 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
314 Math3d::NormalizeVec(ny);
315 Math3d::CrossProduct(ny, nz, nx);
316 std::cout <<
"objectPosition" << std::endl;
317 std::cout << objectPosition << std::endl;
318 objectOrientation << nx.x, ny.x, nz.x, nx.y, ny.y, nz.y, nx.z, ny.z, nz.z;
319 std::cout <<
"objectOrientation" << std::endl;
320 std::cout << objectOrientation << std::endl;
321 cPositionNoise = calculateLocalizationUncertainty(objectList[0].region_left.centroid,
322 objectList[0].region_right.centroid);
324 bChairLocalized =
true;
325 ARMARX_VERBOSE <<
"Finished localizing " << markeredObjectName <<
" in " << refFrame;
327 else if (objectList.size() == numObjectMarker - 1)
331 CVec3dArray allMarkerPositions;
333 for (Object3DList::iterator iter = objectList.begin(); iter != objectList.end(); iter++)
343 std::cout << iter->world_point.x <<
" " << iter->world_point.y <<
" "
344 << iter->world_point.z << std::endl;
345 std::cout << iter->pose.translation.x <<
" " << iter->pose.translation.y <<
" "
346 << iter->pose.translation.z << std::endl;
347 Eigen::Vector3f markerPosition(
348 iter->pose.translation.x, iter->pose.translation.y, iter->pose.translation.z);
349 objectPosition += markerPosition;
350 Vec3d singleMarkerPosition;
351 singleMarkerPosition.x = markerPosition(0);
352 singleMarkerPosition.y = markerPosition(1);
353 singleMarkerPosition.z = markerPosition(2);
354 allMarkerPositions.AddElement(singleMarkerPosition);
358 objectPosition /= numObjectMarker;
361 Vec3d u1, u2, ny, nz, nx, zAxis;
362 Math3d::SubtractVecVec(allMarkerPositions[1], allMarkerPositions[0], u1);
363 Math3d::SubtractVecVec(allMarkerPositions[2], allMarkerPositions[0], u2);
364 Math3d::CrossProduct(u1, u2, ny);
369 if (Math3d::Angle(zAxis, ny) <
M_PI)
384 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
386 Math3d::NormalizeVec(ny);
387 Math3d::CrossProduct(ny, nz, nx);
388 std::cout <<
"objectPosition" << std::endl;
389 std::cout << objectPosition << std::endl;
390 objectOrientation << nx.x, ny.x, nz.x, nx.y, ny.y, nz.y, nx.z, ny.z, nz.z;
391 std::cout <<
"objectOrientation" << std::endl;
392 std::cout << objectOrientation << std::endl;
393 cPositionNoise = calculateLocalizationUncertainty(objectList[0].region_left.centroid,
394 objectList[0].region_right.centroid);
396 bChairLocalized =
true;
397 ARMARX_VERBOSE <<
"Finished localizing " << markeredObjectName <<
" in " << refFrame;
399 else if (objectList.size() == numObjectMarker + 1)
403 CVec3dArray allMarkerPositions;
405 for (Object3DList::iterator iter = objectList.begin(); iter != objectList.end(); iter++)
415 std::cout << iter->world_point.x <<
" " << iter->world_point.y <<
" "
416 << iter->world_point.z << std::endl;
417 std::cout << iter->pose.translation.x <<
" " << iter->pose.translation.y <<
" "
418 << iter->pose.translation.z << std::endl;
419 Eigen::Vector3f markerPosition(
420 iter->pose.translation.x, iter->pose.translation.y, iter->pose.translation.z);
421 objectPosition += markerPosition;
422 Vec3d singleMarkerPosition;
423 singleMarkerPosition.x = markerPosition(0);
424 singleMarkerPosition.y = markerPosition(1);
425 singleMarkerPosition.z = markerPosition(2);
426 allMarkerPositions.AddElement(singleMarkerPosition);
430 objectPosition /= numObjectMarker;
432 std::vector<int> markerPlacementIndex(numObjectMarker);
433 float min1Distance = 0;
435 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
439 for (
int j = 0; j < allMarkerPositions.GetSize(); j++)
441 float temp1Distance = 0;
448 temp1Distance += (allMarkerPositions[i].x - allMarkerPositions[j].x) *
449 (allMarkerPositions[i].x - allMarkerPositions[j].x);
450 temp1Distance += (allMarkerPositions[i].y - allMarkerPositions[j].y) *
451 (allMarkerPositions[i].y - allMarkerPositions[j].y);
452 temp1Distance += (allMarkerPositions[i].z - allMarkerPositions[j].z) *
453 (allMarkerPositions[i].z - allMarkerPositions[j].z);
454 temp1Distance =
sqrt(temp1Distance);
456 if (min1Distance == 0 || temp1Distance < min1Distance)
458 std::cout <<
"minDist " << min1Distance << std::endl;
459 min1Distance = temp1Distance;
461 for (
int k = 0; k < allMarkerPositions.GetSize(); k++)
463 markerPlacementIndex[k] = 0;
466 markerPlacementIndex[i] = 1;
467 markerPlacementIndex[j] = 1;
472 Vec3d minMeanPosition;
473 minMeanPosition.x = 0.0;
474 minMeanPosition.y = 0.0;
475 minMeanPosition.z = 0.0;
476 CVec3dArray otherMarkerPositions;
477 Vec3d otherMeanPosition;
478 otherMeanPosition.x = 0.0;
479 otherMeanPosition.y = 0.0;
480 otherMeanPosition.z = 0.0;
482 for (
int i = 0; i < allMarkerPositions.GetSize(); i++)
484 std::cout << markerPlacementIndex[i] <<
" ";
486 if (markerPlacementIndex[i] == 1)
488 minMeanPosition.x += allMarkerPositions[i].x;
489 minMeanPosition.y += allMarkerPositions[i].y;
490 minMeanPosition.z += allMarkerPositions[i].z;
494 otherMarkerPositions.AddElement(allMarkerPositions[i]);
498 std::cout << std::endl;
499 minMeanPosition.x /= 2.0;
500 minMeanPosition.y /= 2.0;
501 minMeanPosition.z /= 2.0;
502 otherMeanPosition.x /=
float(numObjectMarker - 2);
503 otherMeanPosition.y /=
float(numObjectMarker - 2);
504 otherMeanPosition.z /=
float(numObjectMarker - 2);
505 std::cout <<
"minMean " << minMeanPosition.x <<
" " << minMeanPosition.y <<
" "
506 << minMeanPosition.z << std::endl;
507 std::cout <<
"oterhMean " << otherMeanPosition.x <<
" " << otherMeanPosition.y <<
" "
508 << otherMeanPosition.z << std::endl;
509 Vec3d u1, u2, ny, nz, nx, zAxis;
510 Math3d::SubtractVecVec(otherMarkerPositions[1], otherMarkerPositions[0], u1);
511 Math3d::SubtractVecVec(otherMarkerPositions[2], otherMarkerPositions[0], u2);
512 Math3d::CrossProduct(u1, u2, ny);
516 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
518 if (Math3d::Angle(zAxis, ny) >
M_PI)
533 std::cout <<
"ny " << ny.x <<
" " << ny.y <<
" " << ny.z << std::endl;
535 Math3d::NormalizeVec(ny);
536 Math3d::CrossProduct(ny, nz, nx);
537 std::cout <<
"objectPosition" << std::endl;
538 std::cout << objectPosition << std::endl;
539 objectOrientation << nx.x, ny.x, nz.x, nx.y, ny.y, nz.y, nx.z, ny.z, nz.z;
540 std::cout <<
"objectOrientation" << std::endl;
541 std::cout << objectOrientation << std::endl;
542 cPositionNoise = calculateLocalizationUncertainty(objectList[0].region_left.centroid,
543 objectList[0].region_right.centroid);
545 bChairLocalized =
true;
546 ARMARX_VERBOSE <<
"Finished localizing " << markeredObjectName <<
" in " << refFrame;
555 memoryx::ObjectLocalizationResult result;
556 VirtualRobot::RobotNodePtr rnBase = remoteRobot->getRobotNode(refFrame);
557 VirtualRobot::RobotNodePtr rnCam = remoteRobot->getRobotNode(camFrame);
558 auto agentName = remoteRobot->getName();
564 tmpOrientation->toEigen(), tmpPosition->toEigen(), camFrame, agentName);
565 tmpPose->changeFrame(remoteRobot, refFrame);
566 Eigen::Vector3f zAxisChair(0.0, 0.0, 1.0);
567 Eigen::Vector3f yAxisChair(
568 (tmpPose->toEigen())(0, 1), (tmpPose->toEigen())(1, 1), (tmpPose->toEigen())(2, 1));
569 Eigen::Vector3f xAxisChair = yAxisChair.cross(zAxisChair);
570 yAxisChair = xAxisChair.cross(zAxisChair);
573 objectPoseCorrected(2, 3) = 50.0;
574 objectPoseCorrected(1, 3) += 400.0;
575 objectPoseCorrected.block(0, 0, 3, 1) = xAxisChair;
576 objectPoseCorrected.block(0, 2, 3, 1) = zAxisChair;
577 objectPoseCorrected.block(0, 1, 3, 1) = yAxisChair;
584 result.recognitionCertainty = 1.0;
586 result.objectClassName = markeredObjectName;
587 resultList.push_back(result);
594 ColorMarkerObjectLocalizer::visualizeResults(
const Object3DList& objectList,
595 CByteImage** resultImages)
597 m_pOpenGLVisualizer->ActivateShading(
true);
598 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
601 m_pOpenGLVisualizer->SetProjectionMatrix(getStereoCalibration()->GetRightCalibration());
603 m_pOpenGLVisualizer->Clear();
606 for (
int i = 0; i < (int)objectList.size(); i++)
608 const Object3DEntry& entry = objectList.at(i);
609 CSegmentableDatabase::DrawObjectFromFile(
610 m_pOpenGLVisualizer.get(), entry.sOivFilePath.c_str(), entry.pose);
613 const int nImageIndex = 1;
615 if (resultImages && resultImages[nImageIndex])
617 CByteImage tempImage(resultImages[nImageIndex]);
618 m_pOpenGLVisualizer->GetImage(&tempImage);
619 ::ImageProcessor::FlipY(&tempImage, &tempImage);
620 const int nBytes = 3 * tempImage.width * tempImage.height;
621 const unsigned char* pixels = tempImage.pixels;
622 unsigned char* output = resultImages[nImageIndex]->pixels;
624 for (
int i = 0; i < nBytes; i += 3)
627 const unsigned char g = pixels[i];