StereoVision.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:  StereoVision.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 "StereoVision.h"
00049 
00050 #include "ImageProcessor.h"
00051 #include "ByteImage.h"
00052 #include "Calibration/StereoCalibration.h"
00053 #include "Math/FloatMatrix.h"
00054 #include "Helpers/OptimizedFunctions.h"
00055 #include "Helpers/helpers.h"
00056 
00057 #include <stdio.h>
00058 #include <stdlib.h>
00059 #include <string.h>
00060 #include <math.h>
00061 #include <limits.h>
00062 
00063 
00064 
00065 // *****************************************************************
00066 // Constructor / Destructor
00067 // *****************************************************************
00068 
00069 CStereoVision::CStereoVision()
00070 {
00071 }
00072 
00073 CStereoVision::~CStereoVision()
00074 {
00075 }
00076 
00077 
00078 // ****************************************************************************
00079 // Methods
00080 // ****************************************************************************
00081 
00082 bool CStereoVision::Process(const CByteImage *pLeftImage, const CByteImage *pRightImage, CByteImage *pDepthImage,
00083         int nWindowSize, int d1, int d2, int d_step, int nErrorThreshold)
00084 {
00085         if (pLeftImage->width != pRightImage->width || pLeftImage->height != pRightImage->height ||
00086                 pLeftImage->type != CByteImage::eGrayScale || pRightImage->type != CByteImage::eGrayScale ||
00087                 pDepthImage->width != pLeftImage->width || pDepthImage->height != pLeftImage->height ||
00088                 pDepthImage->type != CByteImage::eGrayScale)
00089         {
00090                 printf("error: input images and/or output image do not match for CStereoVision::ProcessSSD\n");
00091                 return false;
00092         }
00093         
00094         if (d_step == 0)
00095         {
00096                 printf("error: d_step must not be zero for CStereoVision::ProcessSSD\n");
00097                 return false;
00098         }
00099         
00100         if (d_step > 0 && d1 >= d2)
00101         {
00102                 printf("error: if d_step > 0 then d2 must be greater than d1 for CStereoVision::ProcessSSD\n");
00103                 return false;
00104         }
00105         
00106         if (d_step < 0 && d1 <= d2)
00107         {
00108                 printf("error: if d_step < 0 then d1 must be greater than d2 for CStereoVision::ProcessSSD\n");
00109                 return false;
00110         }
00111         
00112         ImageProcessor::Zero(pDepthImage);
00113         
00114         nErrorThreshold *= nWindowSize * nWindowSize;
00115         
00116         // adjust d2 so we can use != instead of <= or >=
00117         int d;
00118         if (d_step > 0)
00119                 for (d = d1; d <= d2; d += d_step);
00120         else if (d_step < 0)
00121                 for (d = d1; d >= d2; d += d_step);
00122         d2 = d + d_step;
00123         
00124         const int width = pLeftImage->width;
00125         const int height = pLeftImage->height;
00126 
00127         const unsigned char *pLeftImageData = pLeftImage->pixels;
00128         const unsigned char *pRightImageData = pRightImage->pixels;
00129         unsigned char *pDepthImageData = pDepthImage->pixels + (nWindowSize / 2) * (width + 1);
00130         
00131         const int max_i = height - nWindowSize + 1;
00132         const int max_j = width - nWindowSize + 1;
00133         
00134         const int start_j = MY_MAX(nWindowSize, d2);
00135         const int diff = width - (max_j - start_j);
00136         const int diff2 = width - nWindowSize;
00137 
00138         for (int i = 0, offset = start_j; i < max_i; i++, offset += diff)
00139         {
00140                 for (int j = start_j; j < max_j; j++, offset++)
00141                 {
00142                         int best_error = INT_MAX;
00143                         int best_d = 0;
00144 
00145                         // find correlation
00146                         for (int d = d1; d != d2; d += d_step)
00147                         {
00148                                 int error = 0;
00149 
00150                                 for (int y = 0, offset2 = offset; y < nWindowSize; y++, offset2 += diff2)
00151                                         for (int x = 0; x < nWindowSize; x++, offset2++)
00152                                                 error += abs(pLeftImageData[offset2] - pRightImageData[offset2 - d]);
00153 
00154                                 if (error < best_error)
00155                                 {
00156                                         best_error = error;
00157                                         best_d = d;
00158                                 }
00159                         }
00160 
00161                         pDepthImageData[i * width + j] = best_error < nErrorThreshold ? best_d : 0;
00162                 }
00163         }
00164 
00165         return true;
00166 }
00167 
00168 
00169 bool CStereoVision::ProcessFast(const CByteImage *pLeftImage, const CByteImage *pRightImage, CByteImage *pDepthImage,
00170         int nWindowSize, int d1, int d2, int d_step, int nErrorThreshold)
00171 {
00172         if (pLeftImage->width != pRightImage->width || pLeftImage->height != pRightImage->height ||
00173                 pLeftImage->type != CByteImage::eGrayScale || pRightImage->type != CByteImage::eGrayScale ||
00174                 pDepthImage->width != pLeftImage->width || pDepthImage->height != pLeftImage->height ||
00175                 pDepthImage->type != CByteImage::eGrayScale)
00176         {
00177                 printf("error: intput images and output image do not match in CStereoVision::ProcessFast\n");
00178                 return false;
00179         }
00180 
00181         if (d_step == 0)
00182         {
00183                 printf("error: d_step must not be zero for CStereoVision::ProcessFast\n");
00184                 return false;
00185         }
00186         
00187         if (d_step > 0 && d1 >= d2)
00188         {
00189                 printf("error: if d_step > 0 then d2 must be greater than d1 for CStereoVision::ProcessFast\n");
00190                 return false;
00191         }
00192         
00193         if (d_step < 0 && d1 <= d2)
00194         {
00195                 printf("error: if d_step < 0 then d1 must be greater than d2 for CStereoVision::ProcessFast\n");
00196                 return false;
00197         }
00198         
00199         //OPTIMIZED_FUNCTION_HEADER_8(StereoVision, pLeftImage, pRightImage, pDepthImage, nWindowSize, d1, d2, d_step, nErrorThreshold)
00200         
00201         _ProcessFast(pLeftImage, pRightImage, pDepthImage, nWindowSize, d1, d2, d_step, nErrorThreshold);
00202         
00203         //OPTIMIZED_FUNCTION_FOOTER
00204         
00205         return true;
00206 }
00207 
00208 
00209 void CStereoVision::_ProcessFast(const CByteImage *pLeftImage, const CByteImage *pRightImage, CByteImage *pDepthImage,
00210         int nWindowSize, int d1, int d2, int d_step, int nErrorThreshold)
00211 {
00212         ImageProcessor::Zero(pDepthImage);
00213 
00214         nErrorThreshold *= nWindowSize * nWindowSize;
00215         
00216         // adjust d2 so we can use != instead of <= or >=
00217         int d;
00218         if (d_step > 0)
00219                 for (d = d1; d <= d2; d += d_step);
00220         else if (d_step < 0)
00221                 for (d = d1; d >= d2; d += d_step);
00222         d2 = d + d_step;
00223                 
00224         const int width = pLeftImage->width;
00225         const int height = pLeftImage->height;
00226         const int nPixels = width * height;
00227         
00228         // allocate memory
00229         int *H_SUM = new int[nWindowSize * width];
00230         int *V_SUM = new int[width];
00231         int *SAD = new int[width];
00232         int *MIN_SSAD = new int[width * height];
00233         
00234         for (int i = 0; i < nPixels; i++)
00235                 MIN_SSAD[i] = nErrorThreshold;
00236         
00237         const int window_offset = - (nWindowSize / 2) * (width + 1);
00238         const int start_c = MY_MAX(nWindowSize, d2) + nWindowSize;
00239         
00240         const unsigned char *pLeftImageData = pLeftImage->pixels;
00241         const unsigned char *pRightImageData = pRightImage->pixels;
00242         unsigned char *pDepthImageData = pDepthImage->pixels + window_offset;
00243 
00244         // run correlation algorithm
00245         for (d = d1; d != d2; d += d_step)
00246         {
00247                 int c, r;
00248                 
00249                 // initialize
00250                 for (r = 0; r < nWindowSize; r++)
00251                 {
00252                         const unsigned char *pLeftImageData_helper = pLeftImageData + r * width;
00253                         const unsigned char *pRightImageData_helper = pRightImageData + r * width - d;
00254                         
00255                         H_SUM[r * width + start_c - 1] = 0;
00256 
00257                         for (c = start_c - nWindowSize; c < start_c; c++)
00258                         {
00259                                 SAD[c] = abs(pLeftImageData_helper[c] - pRightImageData_helper[c]);
00260                                 H_SUM[r * width + start_c - 1] += SAD[c];
00261                         }
00262                         
00263                         for (c = start_c; c < width; c++)
00264                         {
00265                                 SAD[c] = abs(pLeftImageData_helper[c] - pRightImageData_helper[c]);
00266                                 H_SUM[r * width + c] = H_SUM[r * width + c - 1] + SAD[c] - SAD[c - nWindowSize];
00267                         }
00268                 }
00269 
00270                 int *pMinHelper = MIN_SSAD + (nWindowSize - 1) * width; // for topmost_row
00271                 unsigned char *pDepthHelper = pDepthImageData + (nWindowSize - 1) * width; // for topmost_row
00272                 for (c = start_c - 1; c < width; c++)
00273                 {
00274                         V_SUM[c] = 0;
00275                         for (r = 0; r < nWindowSize; r++)
00276                                 V_SUM[c] += H_SUM[r * width + c];
00277 
00278                         // required for writing topmost row
00279                         // <topmost_row>
00280                         if (V_SUM[c] < pMinHelper[c])
00281                         {
00282                                 pMinHelper[c] = V_SUM[c];
00283                                 pDepthHelper[c] = abs(d);
00284                         }
00285                         // </topmost_row>
00286                 }
00287                 
00288                 // go
00289                 for (r = nWindowSize; r < height; r++)
00290                 {
00291                         const unsigned char *pLeftImageData_helper = pLeftImageData + r * width;
00292                         const unsigned char *pRightImageData_helper = pRightImageData + r * width - d;
00293                         
00294                         int *hsum_helper = H_SUM + (r % nWindowSize) * width;
00295                         int *pMinHelper = MIN_SSAD + r * width;
00296                         unsigned char *pDepthHelper = pDepthImageData + r * width;
00297                         
00298                         const int save = hsum_helper[start_c - 1]; // for leftmost_column
00299                         hsum_helper[start_c - 1] = 0;
00300                         for (c = start_c - nWindowSize; c < start_c; c++)
00301                         {
00302                                 SAD[c] = abs(pLeftImageData_helper[c] - pRightImageData_helper[c]);
00303                                 hsum_helper[start_c - 1] += SAD[c];
00304                         }
00305 
00306                         // required for writing leftmost column
00307                         // <leftmost_column>
00308                         const int result = V_SUM[start_c - 1] = V_SUM[start_c - 1] + hsum_helper[start_c - 1] - save;
00309                         if (result < pMinHelper[start_c - 1])
00310                         {
00311                                 pMinHelper[start_c - 1] = result;
00312                                 pDepthHelper[start_c - 1] = abs(d);
00313                         }
00314                         // </leftmost_column>
00315 
00316                         // core loop
00317                         for (c = start_c; c < width; c++)
00318                         {
00319                                 SAD[c] = abs(pLeftImageData_helper[c] - pRightImageData_helper[c]);
00320 
00321                                 const int save = hsum_helper[c];
00322                                 hsum_helper[c] = hsum_helper[c - 1] + SAD[c] - SAD[c - nWindowSize];
00323                                 const int result = V_SUM[c] = V_SUM[c] + hsum_helper[c] - save;
00324 
00325                                 if (result < pMinHelper[c])
00326                                 {
00327                                         pMinHelper[c] = result;
00328                                         pDepthHelper[c] = abs(d);
00329                                 }
00330                         }
00331                 }
00332         }
00333         
00334         // free memory
00335         delete [] H_SUM;
00336         delete [] V_SUM;
00337         delete [] SAD;
00338         delete [] MIN_SSAD;
00339 }


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