31 #include <Calibration/Calibration.h>
32 #include <Calibration/StereoCalibration.h>
33 #include <Image/ByteImage.h>
34 #include <Image/ImageProcessor.h>
36 #ifdef OLP_USE_EARLYVISION
38 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/Descriptors/HueDescriptor.h>
39 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/Descriptors/HueLaplacianDescriptor.h>
40 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/RFCSignatureCalculator.h>
41 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/RFCSignatureFeatureEntry.h>
42 #include </home/staff/schieben/EarlyVision/src/Base/Vision/Recognition/AdditiveRegionImage.h>
55 #include <pcl/io/pcd_io.h>
59 const std::string sObjectName,
60 const int nDescriptorNumber)
63 sFileName.append(sObjectName);
64 ARMARX_VERBOSE_S <<
"Saving object descriptor. File name: " << sFileName.c_str();
68 sFileName +=
"-cloud" + std::string(2 - sDescNum.length(),
'0') + sDescNum +
".pcd";
72 pcl::io::savePCDFileBinary(sFileName, *cloud);
111 const std::string sObjectName,
112 const int nDescriptorNumber)
114 setlocale(LC_NUMERIC,
"C");
119 sFileName.append(sObjectName);
120 std::string sFileNamePointsOnly = sFileName;
121 std::string sFileNamePointsOnlyNoncentered = sFileName;
122 sFileName.append(
"00.dat");
123 sFileNamePointsOnly.append(
"-points00.dat");
124 sFileNamePointsOnlyNoncentered.append(
"-points-noncentered00.dat");
128 ARMARX_VERBOSE_S <<
"Saving object descriptor. File name: " << sFileName.c_str();
129 FILE* pFile = fopen(sFileName.c_str(),
"wt");
130 FILE* pFilePointsOnly = fopen(sFileNamePointsOnly.c_str(),
"wt");
131 FILE* pFilePointsOnlyNoncentered = fopen(sFileNamePointsOnlyNoncentered.c_str(),
"wt");
142 "%e %e %e %e %e %e %e \n",
150 fprintf(pFilePointsOnly,
155 fprintf(pFilePointsOnlyNoncentered,
165 fprintf(pFile,
"%ld \n", pHypothesis->
aNewPoints.size());
167 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
171 "%e %e %e %e %e %e %e \n",
179 fprintf(pFilePointsOnly,
184 fprintf(pFilePointsOnlyNoncentered,
194 fclose(pFilePointsOnly);
195 fclose(pFilePointsOnlyNoncentered);
200 const int nDescriptorNumber,
203 setlocale(LC_NUMERIC,
"C");
207 sFileName.append(sObjectName);
208 sFileName.append(
"00.dat");
210 FILE* pFile = fopen(sFileName.c_str(),
"rt");
214 pFile = fopen(sFileName.c_str(),
"rt");
226 Math3d::SetVec(pHypothesis->
vCenter, 0, 0, 0);
230 int dummy = fscanf(pFile,
"%lu", &nNumPoints);
232 for (
size_t i = 0; i < nNumPoints; i++)
238 dummy += fscanf(pFile,
248 dummy += fscanf(pFile,
"%lu", &nNumPoints);
250 for (
size_t i = 0; i < nNumPoints; i++)
256 dummy += fscanf(pFile,
270 const CByteImage* pHSVImage,
271 const std::vector<CHypothesisPoint*>& aScenePoints,
272 const CCalibration* calibration,
273 std::vector<Vec3d>& aPossibleLocations,
274 const int desiredNumberOfLocations)
276 const int width = pHSVImage->width;
277 const int height = pHSVImage->height;
280 std::vector<float> hueHistogram, saturationHistogram;
283 CByteImage* probabilityImage =
new CByteImage(width, height, CByteImage::eGrayScale);
285 pHSVImage, hueHistogram, saturationHistogram, probabilityImage);
288 ::ImageProcessor::HistogramStretching(
289 probabilityImage, probabilityImage, 0.7f, 1.0f);
294 std::vector<long> rowSums(height, 0);
295 std::vector<long> columnSums(width, 0);
299 for (
int i = 0; i < height; i++)
301 for (
int j = 0; j < width; j++)
303 rowSums[i] += probabilityImage->pixels[i * width + j];
304 columnSums[j] += probabilityImage->pixels[i * width + j];
305 sum += probabilityImage->pixels[i * width + j];
311 for (
int i = 1; i < height; i++)
313 rowSums[i] += rowSums[i - 1];
316 for (
int j = 1; j < width; j++)
318 columnSums[j] += columnSums[j - 1];
323 while ((columnSums[x] < sum) && (x < width))
330 while ((rowSums[y] < sum) && (y < height))
340 std::vector<Vec3d> samplePoints;
342 for (
int i = 0; i < height; i++)
344 for (
int j = 0; j < width; j++)
346 if (rand() % 256 < probabilityImage->pixels[i * width + j])
351 samplePoints.push_back(newVec);
357 std::vector<std::vector<Vec3d>> clusters;
358 std::vector<std::vector<int>> oldIndices;
375 std::vector<Vec2d> locationCandidates;
376 locationCandidates.push_back(vMedian);
378 if (clusters.size() > 1)
380 for (
size_t i = 0; i < clusters.size(); i++)
382 Vec3d vClusterCenter3D;
385 Vec2d vClusterCenter2D = {vClusterCenter3D.x, vClusterCenter3D.y};
386 locationCandidates.push_back(vClusterCenter2D);
393 while ((
int)locationCandidates.size() < desiredNumberOfLocations && numAttempts < 10000)
395 int u = rand() % probabilityImage->width;
396 int v = rand() % probabilityImage->height;
398 if (probabilityImage->pixels[
v * probabilityImage->width + u] > rand() % 500)
401 locationCandidates.push_back(pos);
411 for (
size_t n = 0; n < locationCandidates.size(); n++)
414 probabilityImage, locationCandidates.at(n).x, locationCandidates.at(n).y, 50);
419 probabilityImage->SaveToFile(
filename.c_str());
424 for (
size_t n = 0; n < locationCandidates.size(); n++)
427 Vec3d point1, point2, direction, estimatedPosition, temp1, temp2;
428 calibration->ImageToWorldCoordinates(locationCandidates.at(n), point1, 100.0f,
false);
429 calibration->ImageToWorldCoordinates(locationCandidates.at(n), point2, 200.0f,
false);
430 Math3d::SubtractVecVec(point1, point2, direction);
431 Math3d::NormalizeVec(direction);
432 float fDist, fMinDist = 10000, fBestZ = 500;
434 for (
size_t i = 0; i < aScenePoints.size(); i++)
436 if (Math3d::Length(aScenePoints.at(i)->vPosition) > 0)
438 Math3d::SubtractVecVec(aScenePoints.at(i)->vPosition, point1, temp1);
439 Math3d::CrossProduct(temp1, direction, temp2);
440 fDist = Math3d::Length(temp2);
442 if (fDist < fMinDist)
445 fBestZ = aScenePoints.at(i)->vPosition.z;
451 calibration->ImageToWorldCoordinates(
452 locationCandidates.at(n), estimatedPosition, fBestZ,
false);
455 aPossibleLocations.push_back(estimatedPosition);
459 delete probabilityImage;
464 const CByteImage* pHSVImage,
465 const std::vector<float>& aHueHistogram,
466 const std::vector<float>& aSaturationHistogram,
467 CByteImage* pProbabilityImage)
469 const int nNumScales = 2;
470 const float fVisualizationFactor = 0.33f * 255.0f / (
float)nNumScales;
471 const int nMinNumSubdivisionsX = 4;
475 pProbabilityImage->pixels[i] = 0;
478 std::vector<float> aHueHistogramWindow;
479 aHueHistogramWindow.resize(aHueHistogram.size());
480 std::vector<float> aSaturationHistogramWindow;
481 aSaturationHistogramWindow.resize(aSaturationHistogram.size());
483 for (
int n = 0; n < nNumScales; n++)
486 const int nNumSubdivisionsX = (int)((
double)nMinNumSubdivisionsX * pow(
sqrt(2), n));
487 const int nNumSubdivisionsY =
488 (int)(3.0 / 4.0 * (
double)nMinNumSubdivisionsX * pow(
sqrt(2), n));
491 int nMinX, nMaxX, nMinY, nMaxY;
493 const int nWindowSizeX_3 = nWindowSizeX / 3;
494 const int nWindowSizeY_3 = nWindowSizeY / 3;
496 for (
int i = 0; i < nNumSubdivisionsY; i++)
498 for (
int j = 0; j < nNumSubdivisionsX; j++)
501 for (
int m = -1; m <= 1; m++)
503 nMinX = j * nWindowSizeX + m * nWindowSizeX_3;
504 nMaxX = (j + 1) * nWindowSizeX + m * nWindowSizeX_3;
505 nMinY = i * nWindowSizeY + m * nWindowSizeY_3;
506 nMaxY = (i + 1) * nWindowSizeY + m * nWindowSizeY_3;
534 aSaturationHistogramWindow);
536 const float fHistogramDistance =
540 aSaturationHistogramWindow);
541 const float fCorrelation = 1.0f - (0.25f * fHistogramDistance *
545 unsigned char nCorrelationValueVisualization =
546 (
unsigned char)(fVisualizationFactor * fCorrelation);
548 for (
int k = nMinY; k < nMaxY; k++)
550 for (
int l = nMinX; l < nMaxX; l++)
553 nCorrelationValueVisualization;
564 const CByteImage* pHSVImage,
565 const std::vector<CHypothesisPoint*>& aScenePoints,
566 const CCalibration* calibration,
567 const Vec3d upwardsVector,
572 CByteImage* pResultImage)
575 std::vector<Vec3d> aPossibleLocations;
577 pHypothesis, pHSVImage, aScenePoints, calibration, aPossibleLocations);
590 &aPossibleLocations);
591 delete pPointCloudRegistration;
593 fProbability = 1.0f / (1.0f + 0.12f *
distance);
596 ARMARX_VERBOSE_S <<
"Translation: ( " << vTranslation.x <<
", " << vTranslation.y <<
", "
597 << vTranslation.z <<
")";
603 std::vector<CHypothesisPoint*> aObjectPoints;
608 Math3d::MulMatVec(mOrientation,
609 aObjectPoints.back()->vPosition,
611 aObjectPoints.back()->vPosition);
614 unsigned char r, g, b;
616 if (fProbability > 0.5f)
631 for (
size_t i = 0; i < aObjectPoints.size(); i++)
633 calibration->WorldToImageCoordinates(aObjectPoints.at(i)->vPosition, vPos2D,
false);
635 if (vPos2D.x > 1 && vPos2D.y > 1 && vPos2D.x <
OLP_IMG_WIDTH - 2 &&
638 for (
int j = -1; j <= 1; j++)
641 ->pixels[3 * (((int)vPos2D.y + j) *
OLP_IMG_WIDTH + (int)vPos2D.x)] = r;
643 ->pixels[3 * (((int)vPos2D.y + j) *
OLP_IMG_WIDTH + (int)vPos2D.x) + 1] = g;
645 ->pixels[3 * (((int)vPos2D.y + j) *
OLP_IMG_WIDTH + (int)vPos2D.x) + 2] = b;
647 pResultImage->pixels[3 * ((int)vPos2D.y *
OLP_IMG_WIDTH + (
int)vPos2D.x + j)] =
650 ->pixels[3 * ((int)vPos2D.y *
OLP_IMG_WIDTH + (
int)vPos2D.x + j) + 1] = g;
652 ->pixels[3 * ((int)vPos2D.y *
OLP_IMG_WIDTH + (
int)vPos2D.x + j) + 2] = b;
658 for (
size_t i = 0; i < aObjectPoints.size(); i++)
660 delete aObjectPoints.at(i);
667 const CByteImage* pRGBImage,
668 const std::vector<CHypothesisPoint*>& aScenePoints,
669 const CCalibration* calibration,
670 const Vec3d upwardsVector,
671 std::vector<std::string>& aNames,
672 std::vector<Vec3d>& aPositions,
673 std::vector<Mat3d>& aOrientations,
674 std::vector<float>& aProbabilities)
678 sObjectNamesFileName +=
"names.txt";
679 FILE* pObjectNamesFile = fopen(sObjectNamesFileName.c_str(),
"rt");
681 if (pObjectNamesFile == NULL)
688 int dummy = fscanf(pObjectNamesFile,
"%d", &nNumObjects);
690 int nDescriptorNumber;
691 std::string sObjName;
692 std::vector<int> aDescriptorNumbers;
695 for (
int i = 0; i < nNumObjects; i++)
697 dummy += fscanf(pObjectNamesFile,
"%s", pcObjName);
698 dummy += fscanf(pObjectNamesFile,
"%d", &nDescriptorNumber);
699 sObjName = pcObjName;
700 aNames.push_back(sObjName);
701 aDescriptorNumbers.push_back(nDescriptorNumber);
704 aPositions.resize(nNumObjects);
705 aOrientations.resize(nNumObjects);
706 aProbabilities.resize(nNumObjects);
707 std::vector<float> aDistances;
708 aDistances.resize(nNumObjects);
709 fclose(pObjectNamesFile);
712 CByteImage** pResultImages =
new CByteImage*[nNumObjects];
714 for (
int i = 0; i < nNumObjects; i++)
717 ImageProcessor::CopyImage(pRGBImage, pResultImages[i]);
721 for (
int i = 0; i < nNumObjects; i++)
734 aProbabilities.at(i),
741 for (
int i = 0; i < nNumObjects; i++)
743 std::string sResImgName =
"/home/staff/schieben/datalog/reco00.bmp";
745 pResultImages[i]->SaveToFile(sResImgName.c_str());
746 delete pResultImages[i];
749 delete[] pResultImages;
754 const CByteImage* pHSVImage,
755 const CByteImage* pRGBImage,
756 const std::vector<CHypothesisPoint*>& aScenePoints,
757 const CCalibration* calibration,
758 const Vec3d upwardsVector,
759 const std::string objectName,
760 const int numDescriptors)
763 std::string sFileName = directory +
"reco_dist_" + objectName +
".txt";
764 FILE* pFile = fopen(sFileName.c_str(),
"a");
766 CByteImage* resultImage =
new CByteImage(pRGBImage);
767 ImageProcessor::CopyImage(pRGBImage, resultImage);
771 float probability = -1;
774 for (
int i = 1; i <= numDescriptors; i++)
777 ARMARX_INFO_S <<
"Recognizing " << objectName <<
" (descriptor " << i <<
")";
793 std::string sResImgName = directory +
"reco_result.bmp";
794 resultImage->SaveToFile(sResImgName.c_str());
796 fprintf(pFile,
"\n");
802 const CByteImage* pObjectMask,
803 const std::string sObjectName,
804 const int nDescriptorNumber)
806 #ifdef OLP_USE_EARLYVISION
810 const int nNumberClusters =
812 const float fErrorThreshold =
814 const float fMatchThreshold = 0.5;
819 CRFCSignatureCalculator* pCalc =
new CRFCSignatureCalculator(nNumberClusters);
821 pCalc->SetUseZeroOffset(
false);
822 pCalc->SetErrorThreshold(fErrorThreshold);
823 pCalc->SetCorrespondanceDistanceFactor(fMatchThreshold);
824 pCalc->SetMinConsidered(0.5);
829 CHueDescriptor* pHue =
new CHueDescriptor(0, 10, 255, 10, 255);
830 CHueLaplacianDescriptor* pHueL =
new CHueLaplacianDescriptor(0, 10, 255, 10, 255);
831 pCalc->AddDimension(pHue);
832 pCalc->AddDimension(pHueL);
837 CByteImage* pRGBImageCopy =
new CByteImage(pRGBImage);
838 ImageProcessor::CopyImage(pRGBImage, pRGBImageCopy);
840 if (pRGBImageCopy->width != pRGBImage->width)
845 CByteImage* pObjectMaskCopy =
new CByteImage(pObjectMask);
846 ImageProcessor::CopyImage(pObjectMask, pObjectMaskCopy);
847 CRFCSignatureFeatureEntry* pFeatureDescriptor =
848 (CRFCSignatureFeatureEntry*)pCalc->Train(pRGBImageCopy, pObjectMaskCopy);
853 sFileName.append(sObjectName);
854 sFileName.append(
"00.rfc");
856 ARMARX_VERBOSE_S <<
"\nSaving object descriptor. File name: %s\n", sFileName.c_str());
857 FILE* pFile = fopen(sFileName.c_str(),
"wt");
859 if (!pFeatureDescriptor->WriteToFile(pFile))
870 const int nDescriptorNumber,
871 CRFCSignatureFeatureEntry*& pFeatureDescriptor)
873 #ifdef OLP_USE_EARLYVISION
876 sFileName.append(sObjectName);
877 sFileName.append(
"00.rfc");
879 FILE* pFile = fopen(sFileName.c_str(),
"rt");
883 ARMARX_VERBOSE_S <<
"\nCannot open object file: %s\n\n", sFileName.c_str());
884 pFeatureDescriptor = NULL;
888 pFeatureDescriptor->ReadFromFile(pFile);
896 CByteImage* pRGBImage,
897 const std::vector<CHypothesisPoint*>& aScenePoints,
898 const CCalibration* calibration,
902 CByteImage* pResultImage)
904 #ifdef OLP_USE_EARLYVISION
908 const int nNumberClusters =
910 const float fErrorThreshold =
912 const float fMatchThreshold = 0.5;
913 float fGrowThreshold =
919 CRFCSignatureCalculator* pCalc =
new CRFCSignatureCalculator(nNumberClusters);
921 pCalc->SetUseZeroOffset(
false);
922 pCalc->SetErrorThreshold(fErrorThreshold);
923 pCalc->SetCorrespondanceDistanceFactor(fMatchThreshold);
924 pCalc->SetMinConsidered(0.5);
929 CHueDescriptor* pHue =
new CHueDescriptor(0, 10, 255, 10, 255);
930 CHueLaplacianDescriptor* pHueL =
new CHueLaplacianDescriptor(0, 10, 255, 10, 255);
931 pCalc->AddDimension(pHue);
932 pCalc->AddDimension(pHueL);
938 CFeatureEntry* pfQuery = pFeatureDescriptor;
939 pCalc->PrepareMatching(pRGBImage, NULL, &pfQuery, 1);
940 vector<TRFCMatch> aMatches = pCalc->Match(
941 pfQuery, 2, 2, 4, 4);
946 int nBoarderOffset = pCalc->GetBoarderOffset();
947 int nNumberWindowsX, nNumberWindowsY, nWindowPixelsX, nWindowPixelsY;
949 pCalc->GetNumberWindows(nNumberWindowsX, nNumberWindowsY);
950 pCalc->GetWindowSize(nWindowPixelsX, nWindowPixelsY);
952 CAdditiveRegionImage* pARI =
new CAdditiveRegionImage(
953 nNumberWindowsX, nNumberWindowsY, nWindowPixelsX, nWindowPixelsY, fGrowThreshold);
954 pARI->setOffsets(nBoarderOffset, nBoarderOffset);
956 vector<TRFCMatch>::iterator iter = aMatches.begin();
958 std::vector<TRegionListEntry> aRegionList;
960 while (iter != aMatches.end())
962 TRegionListEntry entry;
963 entry.region = iter->region;
964 entry.fActivation = iter->fMatch;
968 aRegionList.push_back(entry);
974 pARI->set(aRegionList);
975 ARMARX_VERBOSE_S <<
"Evaluation ARI (GrowThreshold: %f) ...\n", fGrowThreshold);
976 std::vector<TResultRegion> aRegions = pARI->calculateRegions();
982 if (pResultImage != NULL)
984 pARI->visualize(pResultImage, aRegions);
985 pResultImage->SaveToFile(
"/home/staff/schieben/datalog/reco.bmp");
990 if (aRegionList.size() > 0)
993 Vec2d vCenter2D = aRegionList.at(0).region.centroid;
994 Vec3d vPoint1, vPoint2, vDirection, vTemp1, vTemp2;
995 calibration->ImageToWorldCoordinates(vCenter2D, vPoint1, 100.0f,
false);
996 calibration->ImageToWorldCoordinates(vCenter2D, vPoint2, 200.0f,
false);
997 Math3d::SubtractVecVec(vPoint1, vPoint2, vDirection);
998 Math3d::NormalizeVec(vDirection);
999 float fDist, fMinDist = 10000, fBestZ = 500;
1001 for (
size_t i = 0; i < aScenePoints.size(); i++)
1003 Math3d::SubtractVecVec(aScenePoints.at(i)->vPosition, vPoint1, vTemp1);
1004 Math3d::CrossProduct(vTemp1, vDirection, vTemp2);
1005 fDist = Math3d::Length(vTemp2);
1007 if (fDist < fMinDist)
1010 fBestZ = aScenePoints.at(i)->vPosition.z;
1015 calibration->ImageToWorldCoordinates(vCenter2D, vPosition, fBestZ,
false);
1017 Math3d::SetMat(mOrientation, Math3d::unit_mat);
1018 fProbability = aRegionList.at(0).fActivation;
1022 Math3d::SetVec(vPosition, 0, 0, 0);
1023 Math3d::SetMat(mOrientation, Math3d::unit_mat);
1032 const CCalibration* calibration,
1033 const std::vector<CHypothesisPoint*>& aScenePoints,
1034 std::vector<std::string>& aNames,
1035 std::vector<Vec3d>& aPositions,
1036 std::vector<Mat3d>& aOrientations,
1037 std::vector<float>& aProbabilities)
1039 #ifdef OLP_USE_EARLYVISION
1041 ImageProcessor::CopyImage(pRGBImage, pResultImage);
1042 CByteImage* pRGBImageCopy =
new CByteImage(pRGBImage);
1043 ImageProcessor::CopyImage(pRGBImage, pRGBImageCopy);
1047 sObjectNamesFileName +=
"names.txt";
1048 FILE* pObjectNamesFile = fopen(sObjectNamesFileName.c_str(),
"rt");
1050 if (pObjectNamesFile == NULL)
1057 fscanf(pObjectNamesFile,
"%d", &nNumObjects);
1058 char pcObjName[100];
1059 int nDescriptorNumber;
1060 std::string sObjName;
1061 std::vector<int> aDescriptorNumbers;
1064 for (
int i = 0; i < nNumObjects; i++)
1066 fscanf(pObjectNamesFile,
"%s", pcObjName);
1067 fscanf(pObjectNamesFile,
"%d", &nDescriptorNumber);
1068 sObjName = pcObjName;
1069 aNames.push_back(sObjName);
1070 aDescriptorNumbers.push_back(nDescriptorNumber);
1073 aPositions.resize(nNumObjects);
1074 aOrientations.resize(nNumObjects);
1075 aProbabilities.resize(nNumObjects);
1076 fclose(pObjectNamesFile);
1079 const int nNumberClusters = 30;
1080 CRFCSignatureFeatureEntry* pFeatureDescriptor =
1081 new CRFCSignatureFeatureEntry(2, nNumberClusters);
1083 for (
int i = 0; i < nNumObjects; i++)
1092 aOrientations.at(i),
1093 aProbabilities.at(i),
1097 delete pFeatureDescriptor;
1099 pResultImage->SaveToFile(
"/home/staff/schieben/datalog/reco.bmp");
1100 delete pResultImage;