30 #include <Image/ByteImage.h>
31 #include <Image/ImageProcessor.h>
32 #include <Calibration/Calibration.h>
33 #include <Calibration/StereoCalibration.h>
35 #ifdef OLP_USE_EARLYVISION
37 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/RFCSignatureCalculator.h>
38 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/RFCSignatureFeatureEntry.h>
39 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/Descriptors/HueDescriptor.h>
40 #include </home/staff/schieben/EarlyVision/src/Base/Features/RFCH/Descriptors/HueLaplacianDescriptor.h>
41 #include </home/staff/schieben/EarlyVision/src/Base/Vision/Recognition/AdditiveRegionImage.h>
54 #include <pcl/io/pcd_io.h>
59 sFileName.append(sObjectName);
60 ARMARX_VERBOSE_S <<
"Saving object descriptor. File name: " << sFileName.c_str();
64 sFileName +=
"-cloud" + std::string(2 - sDescNum.length(),
'0') + sDescNum +
".pcd";
68 pcl::io::savePCDFileBinary(sFileName, *cloud);
107 setlocale(LC_NUMERIC,
"C");
112 sFileName.append(sObjectName);
113 std::string sFileNamePointsOnly = sFileName;
114 std::string sFileNamePointsOnlyNoncentered = sFileName;
115 sFileName.append(
"00.dat");
116 sFileNamePointsOnly.append(
"-points00.dat");
117 sFileNamePointsOnlyNoncentered.append(
"-points-noncentered00.dat");
121 ARMARX_VERBOSE_S <<
"Saving object descriptor. File name: " << sFileName.c_str();
122 FILE* pFile = fopen(sFileName.c_str(),
"wt");
123 FILE* pFilePointsOnly = fopen(sFileNamePointsOnly.c_str(),
"wt");
124 FILE* pFilePointsOnlyNoncentered = fopen(sFileNamePointsOnlyNoncentered.c_str(),
"wt");
134 fprintf(pFile,
"%e %e %e %e %e %e %e \n", pPoint->
vPosition.x - vCenter.x, pPoint->
vPosition.y - vCenter.y, pPoint->
vPosition.z - vCenter.z,
136 fprintf(pFilePointsOnly,
"%e %e %e \n", pPoint->
vPosition.x - vCenter.x, pPoint->
vPosition.y - vCenter.y, pPoint->
vPosition.z - vCenter.z);
143 fprintf(pFile,
"%ld \n", pHypothesis->
aNewPoints.size());
145 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
148 fprintf(pFile,
"%e %e %e %e %e %e %e \n", pPoint->
vPosition.x - vCenter.x, pPoint->
vPosition.y - vCenter.y, pPoint->
vPosition.z - vCenter.z,
150 fprintf(pFilePointsOnly,
"%e %e %e \n", pPoint->
vPosition.x - vCenter.x, pPoint->
vPosition.y - vCenter.y, pPoint->
vPosition.z - vCenter.z);
157 fclose(pFilePointsOnly);
158 fclose(pFilePointsOnlyNoncentered);
165 setlocale(LC_NUMERIC,
"C");
169 sFileName.append(sObjectName);
170 sFileName.append(
"00.dat");
172 FILE* pFile = fopen(sFileName.c_str(),
"rt");
176 pFile = fopen(sFileName.c_str(),
"rt");
188 Math3d::SetVec(pHypothesis->
vCenter, 0, 0, 0);
192 int dummy = fscanf(pFile,
"%lu", &nNumPoints);
194 for (
size_t i = 0; i < nNumPoints; i++)
204 dummy += fscanf(pFile,
"%lu", &nNumPoints);
206 for (
size_t i = 0; i < nNumPoints; i++)
224 const CCalibration* calibration, std::vector<Vec3d>& aPossibleLocations,
const int desiredNumberOfLocations)
226 const int width = pHSVImage->width;
227 const int height = pHSVImage->height;
230 std::vector<float> hueHistogram, saturationHistogram;
233 CByteImage* probabilityImage =
new CByteImage(width, height, CByteImage::eGrayScale);
237 ::ImageProcessor::HistogramStretching(probabilityImage, probabilityImage, 0.7f, 1.0f);
242 std::vector<long> rowSums(height, 0);
243 std::vector<long> columnSums(width, 0);
247 for (
int i = 0; i < height; i++)
249 for (
int j = 0; j < width; j++)
251 rowSums[i] += probabilityImage->pixels[i * width + j];
252 columnSums[j] += probabilityImage->pixels[i * width + j];
253 sum += probabilityImage->pixels[i * width + j];
259 for (
int i = 1; i < height; i++)
261 rowSums[i] += rowSums[i - 1];
264 for (
int j = 1; j < width; j++)
266 columnSums[j] += columnSums[j - 1];
271 while ((columnSums[x] < sum) && (x < width))
278 while ((rowSums[y] < sum) && (y < height))
288 std::vector<Vec3d> samplePoints;
290 for (
int i = 0; i < height; i++)
292 for (
int j = 0; j < width; j++)
294 if (rand() % 256 < probabilityImage->pixels[i * width + j])
299 samplePoints.push_back(newVec);
305 std::vector<std::vector<Vec3d> > clusters;
306 std::vector<std::vector<int> > oldIndices;
317 std::vector<Vec2d> locationCandidates;
318 locationCandidates.push_back(vMedian);
320 if (clusters.size() > 1)
322 for (
size_t i = 0; i < clusters.size(); i++)
324 Vec3d vClusterCenter3D;
327 Vec2d vClusterCenter2D = {vClusterCenter3D.x, vClusterCenter3D.y};
328 locationCandidates.push_back(vClusterCenter2D);
335 while ((
int)locationCandidates.size() < desiredNumberOfLocations && numAttempts < 10000)
337 int u = rand() % probabilityImage->width;
338 int v = rand() % probabilityImage->height;
340 if (probabilityImage->pixels[
v * probabilityImage->width + u] > rand() % 500)
343 locationCandidates.push_back(pos);
353 for (
size_t n = 0; n < locationCandidates.size(); n++)
355 COLPTools::DrawCross(probabilityImage, locationCandidates.at(n).x, locationCandidates.at(n).y, 50);
360 probabilityImage->SaveToFile(
filename.c_str());
365 for (
size_t n = 0; n < locationCandidates.size(); n++)
368 Vec3d point1, point2, direction, estimatedPosition, temp1, temp2;
369 calibration->ImageToWorldCoordinates(locationCandidates.at(n), point1, 100.0f,
false);
370 calibration->ImageToWorldCoordinates(locationCandidates.at(n), point2, 200.0f,
false);
371 Math3d::SubtractVecVec(point1, point2, direction);
372 Math3d::NormalizeVec(direction);
373 float fDist, fMinDist = 10000, fBestZ = 500;
375 for (
size_t i = 0; i < aScenePoints.size(); i++)
377 if (Math3d::Length(aScenePoints.at(i)->vPosition) > 0)
379 Math3d::SubtractVecVec(aScenePoints.at(i)->vPosition, point1, temp1);
380 Math3d::CrossProduct(temp1, direction, temp2);
381 fDist = Math3d::Length(temp2);
383 if (fDist < fMinDist)
386 fBestZ = aScenePoints.at(i)->vPosition.z;
392 calibration->ImageToWorldCoordinates(locationCandidates.at(n), estimatedPosition, fBestZ,
false);
395 aPossibleLocations.push_back(estimatedPosition);
399 delete probabilityImage;
406 const std::vector<float>& aSaturationHistogram, CByteImage* pProbabilityImage)
408 const int nNumScales = 2;
409 const float fVisualizationFactor = 0.33f * 255.0f / (
float)nNumScales;
410 const int nMinNumSubdivisionsX = 4;
414 pProbabilityImage->pixels[i] = 0;
417 std::vector<float> aHueHistogramWindow;
418 aHueHistogramWindow.resize(aHueHistogram.size());
419 std::vector<float> aSaturationHistogramWindow;
420 aSaturationHistogramWindow.resize(aSaturationHistogram.size());
422 for (
int n = 0; n < nNumScales; n++)
425 const int nNumSubdivisionsX = (int)((
double)nMinNumSubdivisionsX * pow(
sqrt(2), n));
426 const int nNumSubdivisionsY = (int)(3.0 / 4.0 * (
double)nMinNumSubdivisionsX * pow(
sqrt(2), n));
429 int nMinX, nMaxX, nMinY, nMaxY;
431 const int nWindowSizeX_3 = nWindowSizeX / 3;
432 const int nWindowSizeY_3 = nWindowSizeY / 3;
434 for (
int i = 0; i < nNumSubdivisionsY; i++)
436 for (
int j = 0; j < nNumSubdivisionsX; j++)
439 for (
int m = -1; m <= 1; m++)
441 nMinX = j * nWindowSizeX + m * nWindowSizeX_3;
442 nMaxX = (j + 1) * nWindowSizeX + m * nWindowSizeX_3;
443 nMinY = i * nWindowSizeY + m * nWindowSizeY_3;
444 nMaxY = (i + 1) * nWindowSizeY + m * nWindowSizeY_3;
470 const float fCorrelation = 1.0f - (0.25f * fHistogramDistance * fHistogramDistance);
473 unsigned char nCorrelationValueVisualization = (
unsigned char)(fVisualizationFactor * fCorrelation);
475 for (
int k = nMinY; k < nMaxY; k++)
477 for (
int l = nMinX; l < nMaxX; l++)
479 pProbabilityImage->pixels[k *
OLP_IMG_WIDTH + l] += nCorrelationValueVisualization;
491 const CCalibration* calibration,
const Vec3d upwardsVector,
Vec3d& vTranslation, Mat3d& mOrientation,
float&
distance,
492 float& fProbability, CByteImage* pResultImage)
495 std::vector<Vec3d> aPossibleLocations;
505 delete pPointCloudRegistration;
507 fProbability = 1.0f / (1.0f + 0.12f *
distance);
510 ARMARX_VERBOSE_S <<
"Translation: ( " << vTranslation.x <<
", " << vTranslation.y <<
", " << vTranslation.z <<
")";
516 std::vector<CHypothesisPoint*> aObjectPoints;
521 Math3d::MulMatVec(mOrientation, aObjectPoints.back()->vPosition, vTranslation, aObjectPoints.back()->vPosition);
524 unsigned char r, g, b;
526 if (fProbability > 0.5f)
541 for (
size_t i = 0; i < aObjectPoints.size(); i++)
543 calibration->WorldToImageCoordinates(aObjectPoints.at(i)->vPosition, vPos2D,
false);
547 for (
int j = -1; j <= 1; j++)
549 pResultImage->pixels[3 * (((int)vPos2D.y + j)*
OLP_IMG_WIDTH + (int)vPos2D.x)] = r;
550 pResultImage->pixels[3 * (((int)vPos2D.y + j)*
OLP_IMG_WIDTH + (int)vPos2D.x) + 1] = g;
551 pResultImage->pixels[3 * (((int)vPos2D.y + j)*
OLP_IMG_WIDTH + (int)vPos2D.x) + 2] = b;
553 pResultImage->pixels[3 * ((int)vPos2D.y *
OLP_IMG_WIDTH + (
int)vPos2D.x + j)] = r;
554 pResultImage->pixels[3 * ((int)vPos2D.y *
OLP_IMG_WIDTH + (
int)vPos2D.x + j) + 1] = g;
555 pResultImage->pixels[3 * ((int)vPos2D.y *
OLP_IMG_WIDTH + (
int)vPos2D.x + j) + 2] = b;
561 for (
size_t i = 0; i < aObjectPoints.size(); i++)
563 delete aObjectPoints.at(i);
572 const CCalibration* calibration,
const Vec3d upwardsVector, std::vector<std::string>& aNames, std::vector<Vec3d>& aPositions,
573 std::vector<Mat3d>& aOrientations, std::vector<float>& aProbabilities)
577 sObjectNamesFileName +=
"names.txt";
578 FILE* pObjectNamesFile = fopen(sObjectNamesFileName.c_str(),
"rt");
580 if (pObjectNamesFile == NULL)
587 int dummy = fscanf(pObjectNamesFile,
"%d", &nNumObjects);
589 int nDescriptorNumber;
590 std::string sObjName;
591 std::vector<int> aDescriptorNumbers;
594 for (
int i = 0; i < nNumObjects; i++)
596 dummy += fscanf(pObjectNamesFile,
"%s", pcObjName);
597 dummy += fscanf(pObjectNamesFile,
"%d", &nDescriptorNumber);
598 sObjName = pcObjName;
599 aNames.push_back(sObjName);
600 aDescriptorNumbers.push_back(nDescriptorNumber);
603 aPositions.resize(nNumObjects);
604 aOrientations.resize(nNumObjects);
605 aProbabilities.resize(nNumObjects);
606 std::vector<float> aDistances;
607 aDistances.resize(nNumObjects);
608 fclose(pObjectNamesFile);
611 CByteImage** pResultImages =
new CByteImage*[nNumObjects];
613 for (
int i = 0; i < nNumObjects; i++)
616 ImageProcessor::CopyImage(pRGBImage, pResultImages[i]);
620 for (
int i = 0; i < nNumObjects; i++)
625 FindObjectRGBD(pHypothesis, pHSVImage, aScenePoints, calibration, upwardsVector, aPositions.at(i), aOrientations.at(i), aDistances.at(i), aProbabilities.at(i), pResultImages[i]);
631 for (
int i = 0; i < nNumObjects; i++)
633 std::string sResImgName =
"/home/staff/schieben/datalog/reco00.bmp";
635 pResultImages[i]->SaveToFile(sResImgName.c_str());
636 delete pResultImages[i];
639 delete[] pResultImages;
646 const CCalibration* calibration,
const Vec3d upwardsVector,
const std::string objectName,
const int numDescriptors)
649 std::string sFileName = directory +
"reco_dist_" + objectName +
".txt";
650 FILE* pFile = fopen(sFileName.c_str(),
"a");
652 CByteImage* resultImage =
new CByteImage(pRGBImage);
653 ImageProcessor::CopyImage(pRGBImage, resultImage);
657 float probability = -1;
660 for (
int i = 1; i <= numDescriptors; i++)
663 ARMARX_INFO_S <<
"Recognizing " << objectName <<
" (descriptor " << i <<
")";
665 FindObjectRGBD(pHypothesis, pHSVImage, aScenePoints, calibration, upwardsVector, position, orientation,
distance, probability, resultImage);
670 std::string sResImgName = directory +
"reco_result.bmp";
671 resultImage->SaveToFile(sResImgName.c_str());
673 fprintf(pFile,
"\n");
688 #ifdef OLP_USE_EARLYVISION
692 const int nNumberClusters = 30;
693 const float fErrorThreshold = 0.5;
694 const float fMatchThreshold = 0.5;
699 CRFCSignatureCalculator* pCalc =
new CRFCSignatureCalculator(nNumberClusters);
701 pCalc->SetUseZeroOffset(
false);
702 pCalc->SetErrorThreshold(fErrorThreshold);
703 pCalc->SetCorrespondanceDistanceFactor(fMatchThreshold);
704 pCalc->SetMinConsidered(0.5);
709 CHueDescriptor* pHue =
new CHueDescriptor(0, 10, 255, 10, 255);
710 CHueLaplacianDescriptor* pHueL =
new CHueLaplacianDescriptor(0, 10, 255, 10, 255);
711 pCalc->AddDimension(pHue);
712 pCalc->AddDimension(pHueL);
717 CByteImage* pRGBImageCopy =
new CByteImage(pRGBImage);
718 ImageProcessor::CopyImage(pRGBImage, pRGBImageCopy);
720 if (pRGBImageCopy->width != pRGBImage->width)
725 CByteImage* pObjectMaskCopy =
new CByteImage(pObjectMask);
726 ImageProcessor::CopyImage(pObjectMask, pObjectMaskCopy);
727 CRFCSignatureFeatureEntry* pFeatureDescriptor = (CRFCSignatureFeatureEntry*) pCalc->Train(pRGBImageCopy, pObjectMaskCopy);
732 sFileName.append(sObjectName);
733 sFileName.append(
"00.rfc");
735 ARMARX_VERBOSE_S <<
"\nSaving object descriptor. File name: %s\n", sFileName.c_str());
736 FILE* pFile = fopen(sFileName.c_str(),
"wt");
738 if (!pFeatureDescriptor->WriteToFile(pFile))
752 #ifdef OLP_USE_EARLYVISION
755 sFileName.append(sObjectName);
756 sFileName.append(
"00.rfc");
758 FILE* pFile = fopen(sFileName.c_str(),
"rt");
762 ARMARX_VERBOSE_S <<
"\nCannot open object file: %s\n\n", sFileName.c_str());
763 pFeatureDescriptor = NULL;
767 pFeatureDescriptor->ReadFromFile(pFile);
777 const CCalibration* calibration,
Vec3d& vPosition, Mat3d& mOrientation,
float& fProbability, CByteImage* pResultImage)
779 #ifdef OLP_USE_EARLYVISION
783 const int nNumberClusters = 30;
784 const float fErrorThreshold = 0.5;
785 const float fMatchThreshold = 0.5;
786 float fGrowThreshold = 0.8;
791 CRFCSignatureCalculator* pCalc =
new CRFCSignatureCalculator(nNumberClusters);
793 pCalc->SetUseZeroOffset(
false);
794 pCalc->SetErrorThreshold(fErrorThreshold);
795 pCalc->SetCorrespondanceDistanceFactor(fMatchThreshold);
796 pCalc->SetMinConsidered(0.5);
801 CHueDescriptor* pHue =
new CHueDescriptor(0, 10, 255, 10, 255);
802 CHueLaplacianDescriptor* pHueL =
new CHueLaplacianDescriptor(0, 10, 255, 10, 255);
803 pCalc->AddDimension(pHue);
804 pCalc->AddDimension(pHueL);
810 CFeatureEntry* pfQuery = pFeatureDescriptor;
811 pCalc->PrepareMatching(pRGBImage, NULL, &pfQuery, 1);
812 vector<TRFCMatch> aMatches = pCalc->Match(pfQuery, 2, 2, 4, 4);
817 int nBoarderOffset = pCalc->GetBoarderOffset();
818 int nNumberWindowsX, nNumberWindowsY, nWindowPixelsX, nWindowPixelsY;
820 pCalc->GetNumberWindows(nNumberWindowsX, nNumberWindowsY);
821 pCalc->GetWindowSize(nWindowPixelsX, nWindowPixelsY);
823 CAdditiveRegionImage* pARI =
new CAdditiveRegionImage(nNumberWindowsX, nNumberWindowsY, nWindowPixelsX, nWindowPixelsY, fGrowThreshold);
824 pARI->setOffsets(nBoarderOffset, nBoarderOffset);
826 vector<TRFCMatch>::iterator iter = aMatches.begin();
828 std::vector<TRegionListEntry> aRegionList;
830 while (iter != aMatches.end())
832 TRegionListEntry entry;
833 entry.region = iter->region;
834 entry.fActivation = iter->fMatch;
838 aRegionList.push_back(entry);
844 pARI->set(aRegionList);
845 ARMARX_VERBOSE_S <<
"Evaluation ARI (GrowThreshold: %f) ...\n", fGrowThreshold);
846 std::vector<TResultRegion> aRegions = pARI->calculateRegions();
852 if (pResultImage != NULL)
854 pARI->visualize(pResultImage, aRegions);
855 pResultImage->SaveToFile(
"/home/staff/schieben/datalog/reco.bmp");
860 if (aRegionList.size() > 0)
863 Vec2d vCenter2D = aRegionList.at(0).region.centroid;
864 Vec3d vPoint1, vPoint2, vDirection, vTemp1, vTemp2;
865 calibration->ImageToWorldCoordinates(vCenter2D, vPoint1, 100.0f,
false);
866 calibration->ImageToWorldCoordinates(vCenter2D, vPoint2, 200.0f,
false);
867 Math3d::SubtractVecVec(vPoint1, vPoint2, vDirection);
868 Math3d::NormalizeVec(vDirection);
869 float fDist, fMinDist = 10000, fBestZ = 500;
871 for (
size_t i = 0; i < aScenePoints.size(); i++)
873 Math3d::SubtractVecVec(aScenePoints.at(i)->vPosition, vPoint1, vTemp1);
874 Math3d::CrossProduct(vTemp1, vDirection, vTemp2);
875 fDist = Math3d::Length(vTemp2);
877 if (fDist < fMinDist)
880 fBestZ = aScenePoints.at(i)->vPosition.z;
885 calibration->ImageToWorldCoordinates(vCenter2D, vPosition, fBestZ,
false);
887 Math3d::SetMat(mOrientation, Math3d::unit_mat);
888 fProbability = aRegionList.at(0).fActivation;
892 Math3d::SetVec(vPosition, 0, 0, 0);
893 Math3d::SetMat(mOrientation, Math3d::unit_mat);
904 std::vector<std::string>& aNames, std::vector<Vec3d>& aPositions, std::vector<Mat3d>& aOrientations, std::vector<float>& aProbabilities)
906 #ifdef OLP_USE_EARLYVISION
908 ImageProcessor::CopyImage(pRGBImage, pResultImage);
909 CByteImage* pRGBImageCopy =
new CByteImage(pRGBImage);
910 ImageProcessor::CopyImage(pRGBImage, pRGBImageCopy);
914 sObjectNamesFileName +=
"names.txt";
915 FILE* pObjectNamesFile = fopen(sObjectNamesFileName.c_str(),
"rt");
917 if (pObjectNamesFile == NULL)
924 fscanf(pObjectNamesFile,
"%d", &nNumObjects);
926 int nDescriptorNumber;
927 std::string sObjName;
928 std::vector<int> aDescriptorNumbers;
931 for (
int i = 0; i < nNumObjects; i++)
933 fscanf(pObjectNamesFile,
"%s", pcObjName);
934 fscanf(pObjectNamesFile,
"%d", &nDescriptorNumber);
935 sObjName = pcObjName;
936 aNames.push_back(sObjName);
937 aDescriptorNumbers.push_back(nDescriptorNumber);
940 aPositions.resize(nNumObjects);
941 aOrientations.resize(nNumObjects);
942 aProbabilities.resize(nNumObjects);
943 fclose(pObjectNamesFile);
946 const int nNumberClusters = 30;
947 CRFCSignatureFeatureEntry* pFeatureDescriptor =
new CRFCSignatureFeatureEntry(2, nNumberClusters);
949 for (
int i = 0; i < nNumObjects; i++)
953 FindObjectRFCH(pFeatureDescriptor, pRGBImageCopy, aScenePoints, calibration, aPositions.at(i), aOrientations.at(i), aProbabilities.at(i), pResultImage);
956 delete pFeatureDescriptor;
958 pResultImage->SaveToFile(
"/home/staff/schieben/datalog/reco.bmp");