00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <new>
00047
00048 #include "ObjectFinderStereo.h"
00049
00050 #include "ObjectFinder.h"
00051 #include "Calibration/StereoCalibration.h"
00052 #include "Interfaces/ObjectClassifierInterface.h"
00053 #include "Interfaces/ObjectEntryFilterInterface.h"
00054 #include "Image/ByteImage.h"
00055
00056 #include <stdio.h>
00057 #include <math.h>
00058
00059
00060
00061
00062
00063
00064
00065 CObjectFinderStereo::CObjectFinderStereo()
00066 {
00067 m_pObjectFinderLeft = new CObjectFinder();
00068 m_pObjectFinderRight = new CObjectFinder();
00069
00070 m_pStereoCalibration = new CStereoCalibration();
00071 m_bOwnCalibration = true;
00072
00073 m_pObjectEntryFilter = 0;
00074 }
00075
00076 CObjectFinderStereo::~CObjectFinderStereo()
00077 {
00078 if(m_bOwnCalibration)
00079 delete m_pStereoCalibration;
00080
00081 delete m_pObjectFinderLeft;
00082 delete m_pObjectFinderRight;
00083 }
00084
00085
00086
00087
00088
00089
00090 bool CObjectFinderStereo::Init(const char *pCameraParameterFileName)
00091 {
00092 if(!m_bOwnCalibration)
00093 m_pStereoCalibration = new CStereoCalibration();
00094
00095 m_bOwnCalibration = true;
00096
00097 return m_pStereoCalibration->LoadCameraParameters(pCameraParameterFileName);
00098 }
00099
00100 void CObjectFinderStereo::Init(CStereoCalibration* pStereoCalibration)
00101 {
00102 if (m_bOwnCalibration)
00103 delete m_pStereoCalibration;
00104
00105 m_bOwnCalibration = false;
00106
00107 m_pStereoCalibration = pStereoCalibration;
00108 }
00109
00110 void CObjectFinderStereo::SetColorParameterSet(const CColorParameterSet *pColorParameterSet)
00111 {
00112 m_pObjectFinderLeft->SetColorParameterSet(pColorParameterSet);
00113 m_pObjectFinderRight->SetColorParameterSet(pColorParameterSet);
00114 }
00115
00116 void CObjectFinderStereo::SetRegionFilter(CRegionFilterInterface *pRegionFilter)
00117 {
00118 m_pObjectFinderLeft->SetRegionFilter(pRegionFilter);
00119 m_pObjectFinderRight->SetRegionFilter(pRegionFilter);
00120 }
00121
00122 CByteImage* CObjectFinderStereo::GetLeftSegmentationResult()
00123 {
00124 return m_pObjectFinderLeft->GetSegmentationResult();
00125 }
00126
00127 CByteImage* CObjectFinderStereo::GetRightSegmentationResult()
00128 {
00129 return m_pObjectFinderRight->GetSegmentationResult();
00130 }
00131
00132
00133 void CObjectFinderStereo::PrepareImages(const CByteImage * const *ppImages, float fROIFactor, bool bCalculateHSVImage)
00134 {
00135 m_pObjectFinderLeft->PrepareImages(ppImages[0], fROIFactor, bCalculateHSVImage);
00136 m_pObjectFinderRight->PrepareImages(ppImages[1], fROIFactor, bCalculateHSVImage);
00137 }
00138
00139 int CObjectFinderStereo::Finalize(float fMinZDistance, float fMaxZDistance, bool bInputImagesAreRectified, ObjectColor finalizeColor, float fMaxYDiff, bool bUseDistortionParameters)
00140 {
00141 m_pObjectFinderLeft->Finalize();
00142 m_pObjectFinderRight->Finalize();
00143
00144 const int nRet = DetermineMatches(m_pObjectFinderLeft->m_objectList, m_pObjectFinderRight->m_objectList, fMinZDistance, fMaxZDistance, bInputImagesAreRectified, bUseDistortionParameters, finalizeColor, fMaxYDiff);
00145
00146
00147 UpdateObjectFinderLists(m_pObjectFinderLeft->m_objectList, m_pObjectFinderRight->m_objectList);
00148
00149 return nRet;
00150 }
00151
00152
00153 void CObjectFinderStereo::FindObjects(const CByteImage * const *ppImages, CByteImage **ppResultImages, ObjectColor color, int nMinPointsPerRegion, bool bShowSegmentedImage)
00154 {
00155 CByteImage *pResultImageLeft = ppResultImages ? ppResultImages[0] : 0;
00156 CByteImage *pResultImageRight = ppResultImages ? ppResultImages[1] : 0;
00157
00158 m_pObjectFinderLeft->FindObjects(ppImages[0], pResultImageLeft, color, nMinPointsPerRegion, bShowSegmentedImage);
00159 m_pObjectFinderRight->FindObjects(ppImages[1], pResultImageRight, color, nMinPointsPerRegion, bShowSegmentedImage);
00160 }
00161
00162 void CObjectFinderStereo::FindObjects(const CByteImage * const *ppImages, CByteImage **ppResultImages, ObjectColor color, int nMinPointsPerRegion, CByteImage **ppSegmentedResultImages)
00163 {
00164 CByteImage *pResultImageLeft = ppResultImages ? ppResultImages[0] : 0;
00165 CByteImage *pResultImageRight = ppResultImages ? ppResultImages[1] : 0;
00166
00167 m_pObjectFinderLeft->FindObjects(ppImages[0], pResultImageLeft, color, nMinPointsPerRegion, ppSegmentedResultImages[0]);
00168 m_pObjectFinderRight->FindObjects(ppImages[1], pResultImageRight, color, nMinPointsPerRegion, ppSegmentedResultImages[1]);
00169 }
00170
00171 void CObjectFinderStereo::FindObjects(const CByteImage * const *ppImages, CByteImage **ppResultImages, ObjectColor colorName, int hue, int hue_tol, int min_sat, int max_sat, int min_v, int max_v, int nMinPointsPerRegion, bool bShowSegmentedImage)
00172 {
00173 CByteImage *pResultImageLeft = ppResultImages ? ppResultImages[0] : 0;
00174 CByteImage *pResultImageRight = ppResultImages ? ppResultImages[1] : 0;
00175
00176 m_pObjectFinderLeft->FindObjects(ppImages[0], pResultImageLeft, colorName, hue, hue_tol, min_sat, max_sat, min_v, max_v, nMinPointsPerRegion, bShowSegmentedImage);
00177 m_pObjectFinderRight->FindObjects(ppImages[1], pResultImageRight, colorName, hue, hue_tol, min_sat, max_sat, min_v, max_v, nMinPointsPerRegion, bShowSegmentedImage);
00178 }
00179
00180 void CObjectFinderStereo::FindObjectsInSegmentedImage(const CByteImage * const *ppImages, CByteImage **ppResultImages, ObjectColor color, int nMinPointsPerRegion, bool bShowSegmentedImage)
00181 {
00182 CByteImage *pResultImageLeft = ppResultImages ? ppResultImages[0] : 0;
00183 CByteImage *pResultImageRight = ppResultImages ? ppResultImages[1] : 0;
00184
00185 m_pObjectFinderLeft->FindObjectsInSegmentedImage(ppImages[0], pResultImageLeft, color, nMinPointsPerRegion, bShowSegmentedImage);
00186 m_pObjectFinderRight->FindObjectsInSegmentedImage(ppImages[1], pResultImageRight, color, nMinPointsPerRegion, bShowSegmentedImage);
00187 }
00188
00189
00190 int CObjectFinderStereo::DetermineMatches(Object2DList &resultListLeft, Object2DList &resultListRight, float fMinZDistance, float fMaxZDistance, bool bInputImagesAreRectified, bool bUseDistortionParameters, ObjectColor finalizeColor, float fMaxEpipolarDistance)
00191 {
00192
00193 Object3DList oldObjectList = m_objectList;
00194
00195 if (finalizeColor == eNone)
00196 {
00197 m_objectList.clear();
00198 }
00199 else
00200 {
00201 for (int i = 0; i < (int) m_objectList.size(); i++)
00202 {
00203 if (m_objectList.at(i).color == finalizeColor)
00204 {
00205 m_objectList.erase(m_objectList.begin() + i);
00206 i--;
00207 }
00208 }
00209 }
00210
00211 int i, j;
00212
00213 for (i = 0; i < (int) resultListLeft.size(); i++)
00214 resultListLeft.at(i).reserved = 0;
00215
00216 for (i = 0; i < (int) resultListRight.size(); i++)
00217 resultListRight.at(i).reserved = 0;
00218
00219
00220 for (i = 0; i < (int) oldObjectList.size(); i++)
00221 {
00222 Object3DEntry &objectEntry = oldObjectList.at(i);
00223
00224 if (finalizeColor != eNone && finalizeColor != objectEntry.color)
00225 continue;
00226
00227 const int region_left_id = objectEntry.region_id_left;
00228 const int region_right_id = objectEntry.region_id_right;
00229 int nMatchLeft = -1, nMatchRight = -1;
00230
00231 for (j = 0; j < (int) resultListLeft.size(); j++)
00232 {
00233 if (resultListLeft.at(j).id == region_left_id)
00234 {
00235 nMatchLeft = j;
00236 break;
00237 }
00238 }
00239
00240 for (j = 0; j < (int) resultListRight.size(); j++)
00241 if (resultListRight.at(j).id == region_right_id)
00242 {
00243 nMatchRight = j;
00244 break;
00245 }
00246
00247 if (nMatchLeft != -1 && nMatchRight != -1)
00248 {
00249
00250 objectEntry.region_left = resultListLeft.at(nMatchLeft).region;
00251 objectEntry.region_right = resultListRight.at(nMatchRight).region;
00252 m_pStereoCalibration->Calculate3DPoint(objectEntry.region_left.centroid, objectEntry.region_right.centroid, objectEntry.pose.translation, bInputImagesAreRectified, bUseDistortionParameters);
00253
00254 Math3d::SetVec(objectEntry.world_point, objectEntry.pose.translation);
00255
00256 if (objectEntry.pose.translation.z >= fMinZDistance && objectEntry.pose.translation.z <= fMaxZDistance &&
00257 (!m_pObjectEntryFilter || m_pObjectEntryFilter->CheckEntry(objectEntry)))
00258 {
00259 resultListLeft.at(nMatchLeft).reserved = 1;
00260 resultListRight.at(nMatchRight).reserved = 1;
00261 m_objectList.push_back(objectEntry);
00262 }
00263 }
00264 }
00265
00266
00267 for (i = 0; i < (int) resultListLeft.size(); i++)
00268 {
00269 Object2DEntry &entryLeft = resultListLeft.at(i);
00270
00271 if (!entryLeft.reserved && (finalizeColor == eNone || entryLeft.color == finalizeColor))
00272 {
00273
00274 float best_diff = fMaxEpipolarDistance;
00275 int best_j = -1;
00276
00277 for (j = 0; j < (int) resultListRight.size(); j++)
00278 {
00279 Object2DEntry &entryRight = resultListRight.at(j);
00280
00281 if (!entryRight.reserved)
00282 {
00283 const float ratio = entryLeft.region.nPixels < entryRight.region.nPixels ? (float) entryLeft.region.nPixels / entryRight.region.nPixels : (float) entryRight.region.nPixels / entryLeft.region.nPixels;
00284 const float ratio2 = entryLeft.region.ratio < entryRight.region.ratio ? (float) entryLeft.region.ratio / entryRight.region.ratio : (float) entryRight.region.ratio / entryLeft.region.ratio;
00285 const float y_diff = bInputImagesAreRectified ? fabsf(entryLeft.region.centroid.y - entryRight.region.centroid.y) : fabsf(m_pStereoCalibration->CalculateEpipolarLineInLeftImageDistance(entryLeft.region.centroid, entryRight.region.centroid));
00286
00287 Vec3d position;
00288 m_pStereoCalibration->Calculate3DPoint(entryLeft.region.centroid, entryRight.region.centroid, position, bInputImagesAreRectified, bUseDistortionParameters);
00289
00290
00291
00292 if (ratio > 0.5f && ratio2 > 0.5f && y_diff < fMaxEpipolarDistance &&
00293 (entryLeft.type == entryRight.type || entryLeft.type == eCompactObject || entryRight.type == eCompactObject) && entryLeft.color == entryRight.color && (finalizeColor == eNone || entryLeft.color == finalizeColor) &&
00294 position.z >= fMinZDistance && position.z <= fMaxZDistance && y_diff < best_diff)
00295 {
00296 best_diff = y_diff;
00297 best_j = j;
00298 }
00299 }
00300 }
00301
00302 if (best_j != -1)
00303 {
00304 Object2DEntry &entryRight = resultListRight.at(best_j);
00305 Object3DEntry entry;
00306
00307 entry.region_left = entryLeft.region;
00308 entry.region_right = entryRight.region;
00309 entry.region_id_left = entryLeft.id;
00310 entry.region_id_right = entryRight.id;
00311 entry.color = entryLeft.color;
00312 entry.type = entryLeft.type == eCompactObject ? entryRight.type : entryLeft.type;
00313 entry.sName = "CompactObject";
00314 entry.sOivFilePath = "";
00315
00316 m_pStereoCalibration->Calculate3DPoint(entry.region_left.centroid, entry.region_right.centroid, entry.pose.translation, bInputImagesAreRectified, bUseDistortionParameters);
00317
00318 Math3d::SetVec(entry.world_point, entry.pose.translation);
00319
00320 if (!m_pObjectEntryFilter || m_pObjectEntryFilter->CheckEntry(entry))
00321 {
00322 entryLeft.reserved = 1;
00323 entryRight.reserved = 1;
00324 m_objectList.push_back(entry);
00325 }
00326 }
00327 }
00328 }
00329
00330
00331 for (i = 0; i < (int) m_objectClassifierList.size(); i++)
00332 m_objectClassifierList.at(i)->Classify(m_objectList);
00333
00334 return (int) m_objectList.size();
00335 }
00336
00337 void CObjectFinderStereo::UpdateObjectFinderLists(Object2DList &resultListLeft, Object2DList &resultListRight)
00338 {
00339 int i;
00340
00341
00342 for (i = 0; i < (int) resultListLeft.size(); i++)
00343 if (!resultListLeft.at(i).reserved)
00344 {
00345 resultListLeft.erase(resultListLeft.begin() + i);
00346 i--;
00347 }
00348
00349
00350 for (i = 0; i < (int) resultListRight.size(); i++)
00351 if (!resultListRight.at(i).reserved)
00352 {
00353 resultListRight.erase(resultListRight.begin() + i);
00354 i--;
00355 }
00356
00357
00358 for (i = 0; i < (int) m_objectList.size(); i++)
00359 {
00360 int j;
00361
00362 const Object3DEntry &object = m_objectList.at(i);
00363
00364 for (j = 0; j < (int) resultListLeft.size(); j++)
00365 {
00366 Object2DEntry &entry = resultListLeft.at(j);
00367
00368 if (entry.color == object.color && entry.region.centroid.x == object.region_left.centroid.x && entry.region.centroid.y == object.region_left.centroid.y && entry.region.nPixels == object.region_left.nPixels)
00369 entry.type = object.type;
00370 }
00371
00372 for (j = 0; j < (int) resultListRight.size(); j++)
00373 {
00374 Object2DEntry &entry = resultListRight.at(j);
00375
00376 if (entry.color == object.color && entry.region.centroid.x == object.region_right.centroid.x && entry.region.centroid.y == object.region_right.centroid.y && entry.region.nPixels == object.region_right.nPixels)
00377 entry.type = object.type;
00378 }
00379 }
00380 }
00381
00382 void CObjectFinderStereo::ClearObjectList()
00383 {
00384 m_objectList.clear();
00385 m_pObjectFinderLeft->ClearObjectList();
00386 m_pObjectFinderRight->ClearObjectList();
00387 }
00388
00389 void CObjectFinderStereo::AddObject(const Object3DEntry &entry)
00390 {
00391 m_objectList.push_back(entry);
00392
00393 Object2DEntry entry2D;
00394 entry2D.type = entry.type;
00395 entry2D.color = entry.color;
00396
00397 entry2D.id = entry.region_id_left;
00398 entry2D.region = entry.region_left;
00399 m_pObjectFinderLeft->AddObject(entry2D);
00400
00401 entry2D.id = entry.region_id_right;
00402 entry2D.region = entry.region_right;
00403 m_pObjectFinderRight->AddObject(entry2D);
00404 }
00405
00406
00407 void CObjectFinderStereo::AddObjectClassifier(CObjectClassifierInterface *pObjectClassifier)
00408 {
00409 m_objectClassifierList.push_back(pObjectClassifier);
00410 }
00411
00412 void CObjectFinderStereo::RemoveObjectClassifier(CObjectClassifierInterface *pObjectClassifier)
00413 {
00414 for (std::vector<CObjectClassifierInterface*>::iterator it = m_objectClassifierList.begin(); it != m_objectClassifierList.end(); it++)
00415 {
00416 if (*it == pObjectClassifier)
00417 {
00418 m_objectClassifierList.erase(it);
00419 break;
00420 }
00421 }
00422 }
00423
00424 void CObjectFinderStereo::ClearObjectClassifierList()
00425 {
00426 m_objectClassifierList.clear();
00427 }