RANSAC.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:  RANSAC.cpp
00037 // Author:    Pedram Azad
00038 // Date:      14.12.2009
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs
00047 
00048 #include "RANSAC.h"
00049 
00050 #include "Structs/Structs.h"
00051 #include "Math/Math2d.h"
00052 #include "Math/Math3d.h"
00053 #include "Math/LinearAlgebra.h"
00054 
00055 #include <stdlib.h>
00056 #include <math.h>
00057 
00058 
00059 
00060 // ****************************************************************************
00061 // Functions
00062 // ****************************************************************************
00063 
00064 bool RANSAC::RANSACAffineTransformation(const CDynamicArrayTemplate<PointPair2d> &matchCandidates, CDynamicArrayTemplate<PointPair2d> &resultMatches, float fRANSACThreshold, int nIterations)
00065 {
00066         const int nMatchCandidates = matchCandidates.GetSize();
00067         
00068         if (nMatchCandidates < 3)
00069         {
00070                 printf("error: at least 3 match candidates must be provided for RANSAC::RANSACAffineTransformation (%i provided)\n", nMatchCandidates);
00071                 return false;
00072         }
00073         
00074         Mat3d best_B;
00075         int i, max = 0;
00076 
00077         for (i = 0; i < nIterations; i++)
00078         {
00079                 // identify 3 different points
00080                 const int nFirstIndex = rand() % nMatchCandidates;
00081                 
00082                 int nTempIndex;
00083                 
00084                 do { nTempIndex = rand() % nMatchCandidates; } while (nTempIndex == nFirstIndex);
00085                 const int nSecondIndex = nTempIndex;
00086                 
00087                 do { nTempIndex = rand() % nMatchCandidates; } while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex);
00088                 
00089                 Vec2d pFeaturesLeft[3];
00090                 Vec2d pFeaturesRight[3];
00091                 
00092                 Math2d::SetVec(pFeaturesLeft[0], matchCandidates[nFirstIndex].p1);
00093                 Math2d::SetVec(pFeaturesLeft[1], matchCandidates[nSecondIndex].p1);
00094                 Math2d::SetVec(pFeaturesLeft[2], matchCandidates[nTempIndex].p1);
00095                 
00096                 Math2d::SetVec(pFeaturesRight[0], matchCandidates[nFirstIndex].p2);
00097                 Math2d::SetVec(pFeaturesRight[1], matchCandidates[nSecondIndex].p2);
00098                 Math2d::SetVec(pFeaturesRight[2], matchCandidates[nTempIndex].p2);
00099                 
00100                 // calculate affine transformation for these points
00101                 Mat3d B;
00102                 LinearAlgebra::DetermineAffineTransformation(pFeaturesRight, pFeaturesLeft, 3, B);
00103                 
00104                 // count support
00105                 int nSupport = 0;
00106                 for (int j = 0; j < nMatchCandidates; j++)
00107                 {
00108                         Vec2d p;
00109                         Math2d::ApplyHomography(B, matchCandidates[j].p2, p);
00110                         
00111                         const float distance = Math2d::Distance(p, matchCandidates[j].p1);
00112                         
00113                         if (distance < fRANSACThreshold)
00114                                 nSupport++;
00115                 }
00116                 
00117                 // store if it is the current maximum
00118                 if (nSupport > max)
00119                 {
00120                         max = nSupport;
00121                         Math3d::SetMat(best_B, B);
00122                 }
00123         }
00124 
00125         // filter matches
00126         resultMatches.Clear();
00127         
00128         for (i = 0; i < nMatchCandidates; i++)
00129         {
00130                 Vec2d p;
00131                 Math2d::ApplyHomography(best_B, matchCandidates[i].p2, p);
00132                 
00133                 const float distance = Math2d::Distance(p, matchCandidates[i].p1);
00134                 
00135                 if (distance < fRANSACThreshold)
00136                 {
00137                         PointPair2d match;
00138                         Math2d::SetVec(match.p1, matchCandidates[i].p1);
00139                         Math2d::SetVec(match.p2, matchCandidates[i].p2);
00140                         
00141                         resultMatches.AddElement(match);
00142                 }
00143         }
00144 
00145         return true;
00146 }
00147 
00148 bool RANSAC::RANSACHomography(const CDynamicArrayTemplate<PointPair2d> &matchCandidates, CDynamicArrayTemplate<PointPair2d> &resultMatches, float fRANSACThreshold, int nIterations)
00149 {
00150         const int nMatchCandidates = matchCandidates.GetSize();
00151         
00152         if (nMatchCandidates < 4)
00153         {
00154                 printf("error: at least 4 match candidates must be provided for RANSAC::RANSACHomography (%i provided)\n", nMatchCandidates);
00155                 return false;
00156         }
00157         
00158         Mat3d best_B;
00159         int i, max = 0;
00160         
00161         for (i = 0; i < nIterations; i++)
00162         {
00163                 // identify 4 different points
00164                 const int nFirstIndex = rand() % nMatchCandidates;
00165                 
00166                 int nTempIndex;
00167                 
00168                 do { nTempIndex = rand() % nMatchCandidates; } while (nTempIndex == nFirstIndex);
00169                 const int nSecondIndex = nTempIndex;
00170                 
00171                 do { nTempIndex = rand() % nMatchCandidates; } while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex);
00172                 const int nThirdIndex = nTempIndex;
00173                 
00174                 do { nTempIndex = rand() % nMatchCandidates; } while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex || nTempIndex == nThirdIndex);
00175                 
00176                 Vec2d pFeaturesLeft[4];
00177                 Vec2d pFeaturesRight[4];
00178                 
00179                 Math2d::SetVec(pFeaturesLeft[0], matchCandidates[nFirstIndex].p1);
00180                 Math2d::SetVec(pFeaturesLeft[1], matchCandidates[nSecondIndex].p1);
00181                 Math2d::SetVec(pFeaturesLeft[2], matchCandidates[nThirdIndex].p1);
00182                 Math2d::SetVec(pFeaturesLeft[3], matchCandidates[nTempIndex].p1);
00183                 
00184                 Math2d::SetVec(pFeaturesRight[0], matchCandidates[nFirstIndex].p2);
00185                 Math2d::SetVec(pFeaturesRight[1], matchCandidates[nSecondIndex].p2);
00186                 Math2d::SetVec(pFeaturesRight[2], matchCandidates[nThirdIndex].p2);
00187                 Math2d::SetVec(pFeaturesRight[3], matchCandidates[nTempIndex].p1);
00188                 
00189                 // calculate affine transformation for these points
00190                 Mat3d B;
00191                 LinearAlgebra::DetermineHomography(pFeaturesRight, pFeaturesLeft, 4, B, false);
00192                 
00193                 // count support
00194                 int nSupport = 0;
00195                 for (int j = 0; j < nMatchCandidates; j++)
00196                 {
00197                         Vec2d p;
00198                         Math2d::ApplyHomography(B, matchCandidates[j].p2, p);
00199                         
00200                         const float distance = Math2d::Distance(p, matchCandidates[j].p1);
00201                         
00202                         if (distance < fRANSACThreshold)
00203                                 nSupport++;
00204                 }
00205                 
00206                 // store if it is the current maximum
00207                 if (nSupport > max)
00208                 {
00209                         max = nSupport;
00210                         Math3d::SetMat(best_B, B);
00211                 }
00212         }
00213         
00214         // filter matches
00215         resultMatches.Clear();
00216         
00217         for (i = 0; i < nMatchCandidates; i++)
00218         {
00219                 Vec2d p;
00220                 Math2d::ApplyHomography(best_B, matchCandidates[i].p2, p);
00221                 
00222                 const float distance = Math2d::Distance(p, matchCandidates[i].p1);
00223                 
00224                 if (distance < fRANSACThreshold)
00225                 {
00226                         PointPair2d match;
00227                         Math2d::SetVec(match.p1, matchCandidates[i].p1);
00228                         Math2d::SetVec(match.p2, matchCandidates[i].p2);
00229                         
00230                         resultMatches.AddElement(match);
00231                 }
00232         }
00233         
00234         return true;
00235 }
00236 
00237 bool RANSAC::RANSAC3DPlane(const CVec3dArray &pointCandidates, CVec3dArray &resultPoints, float fRANSACThreshold, int nIterations)
00238 {
00239         const int nPointCandidates = pointCandidates.GetSize();
00240         
00241         if (nPointCandidates < 3)
00242         {
00243                 printf("error: at least 3 point candidates must be provided for RANSAC::RANSAC3DPlane (%i provided)\n", nPointCandidates);
00244                 return false;
00245         }
00246         
00247         int i, max = 0;
00248         float best_c = 0.0f;
00249         Vec3d best_n = { 0.0f, 0.0f };
00250         
00251         for (i = 0; i < nIterations; i++)
00252         {
00253                 // identify 3 different points
00254                 const int nFirstIndex = rand() % nPointCandidates;
00255                 
00256                 int nTempIndex;
00257                 
00258                 do { nTempIndex = rand() % nPointCandidates; } while (nTempIndex == nFirstIndex);
00259                 const int nSecondIndex = nTempIndex;
00260                 
00261                 do { nTempIndex = rand() % nPointCandidates; } while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex);
00262                 
00263                 const Vec3d &p1 = pointCandidates[nFirstIndex];
00264                 const Vec3d &p2 = pointCandidates[nSecondIndex];
00265                 const Vec3d &p3 = pointCandidates[nTempIndex];
00266                 
00267                 Vec3d u1, u2, n;
00268                 Math3d::SubtractVecVec(p2, p1, u1);
00269                 Math3d::SubtractVecVec(p3, p1, u2);
00270                 Math3d::CrossProduct(u1, u2, n);
00271                 Math3d::NormalizeVec(n);
00272                 const float c = Math3d::ScalarProduct(n, p1);
00273                 
00274                 // count support
00275                 int nSupport = 0;
00276                 for (int j = 0; j < nPointCandidates; j++)
00277                         if (fabsf(Math3d::ScalarProduct(n, pointCandidates[j]) - c) <= fRANSACThreshold)
00278                                 nSupport++;
00279                 
00280                 // store if it is the current maximum
00281                 if (nSupport > max)
00282                 {
00283                         max = nSupport;
00284                         Math3d::SetVec(best_n, n);
00285                         best_c = c;
00286                 }
00287         }
00288         
00289         // filter points
00290         resultPoints.Clear();
00291         
00292         for (i = 0; i < nPointCandidates; i++)
00293         {
00294                 if (fabsf(Math3d::ScalarProduct(pointCandidates[i], best_n) - best_c) <= fRANSACThreshold)
00295                         resultPoints.AddElement(pointCandidates[i]);
00296         }
00297         
00298         return true;
00299 }


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:58