ObjectFinderStereo.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  ObjectFinderStereo.cpp
00037 // Author:    Pedram Azad
00038 // Date:      2005
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs
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 // Constructor / Destructor
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 // Methods
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         // update object lists of (2D) CObjectFinder objects
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         // create copy of current object list
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         // add already existing region pairs
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                         // calculate 3D point
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         // add new region pairs
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                         // find best match in list for right image
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                                         //printf("%.2f %.2f -- %.2f %.2f -- %.2f %.2f %.2f\n", entryLeft.region.centroid.x, entryLeft.region.centroid.y, entryRight.region.centroid.x, entryRight.region.centroid.y, ratio, y_diff, position.z);
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         // run object classifiers
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         // delete unmatched entries in left 2D list
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         // delete unmatched entries in right 2D list
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         // assign types to 2D lists
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 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57