stereo.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2009, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 #include <frame_common/stereo.h>
00036 #include <xmmintrin.h>
00037 
00038 namespace frame_common
00039 {
00040 
00041   // !! Must free memory after using
00042 
00043   uint8_t *grab_16x16(uint8_t *im, int xim, int x, int y)
00044   { 
00045     char sub[256];
00046     if (1) 
00047       {
00048         for (size_t i = 0; i < 16; i++)
00049                 memcpy(sub + 16 * i, im + x + (y + i) * xim, 16);
00050       } 
00051     else 
00052       {
00053 #define COPY16(N)                                                       \
00054       _mm_storeu_ps((float*)(sub + 16 * N), _mm_loadu_ps((float*)(im + x + (y + N) * xim)));
00055         COPY16(0)
00056               COPY16(1)
00057               COPY16(2)
00058               COPY16(3)
00059               COPY16(4)
00060               COPY16(5)
00061               COPY16(6)
00062               COPY16(7)
00063               COPY16(8)
00064               COPY16(9)
00065               COPY16(10)
00066               COPY16(11)
00067               COPY16(12)
00068               COPY16(13)
00069               COPY16(14)
00070               COPY16(15)
00071             }
00072     uint8_t *return_val = new uint8_t[257];
00073     return_val[256] = '\0';
00074     memcpy(return_val, sub, 256);
00075     return return_val;
00076   }
00077 
00078   SparseStereo::SparseStereo(const cv::Mat& leftImg, const cv::Mat& rightImg, 
00079                              bool use_grad_im, uint max_disparity)
00080   {
00081     //    printf("Doing sparse stereo with ndisp = %d\n", max_disparity);
00082 
00083     lim = leftImg;
00084     rim = rightImg;
00085     use_grad_img = use_grad_im;
00086     max_disp = max_disparity;
00087     if (use_grad_im)
00088       {
00089               uint8_t *buf = new uint8_t[lim.cols * lim.rows];
00090               lgrad = new uint8_t[lim.cols * lim.rows];
00091               rgrad = new uint8_t[rim.cols*rim.rows];
00092               do_prefilter_xsobel(lim.data, lgrad, lim.cols, lim.rows, ftzero, buf );
00093               do_prefilter_xsobel(rim.data, rgrad, rim.cols, rim.rows, ftzero, buf );
00094               delete [] buf;
00095       }
00096     else
00097       {
00098               lgrad = NULL;
00099               rgrad = NULL;
00100       }
00101   }
00102 
00103   SparseStereo::~SparseStereo()
00104   {
00105     delete [] lgrad;
00106     delete [] rgrad;
00107   }
00108 
00109   double SparseStereo::lookup_disparity(int x, int y) const
00110   {
00111     uint8_t* refpat, *rim_as_arr, *lim_as_arr;
00112     int w = lim.cols;
00113     int h = lim.rows;
00114     if(use_grad_img && lgrad)
00115       {
00116               lim_as_arr = lgrad;
00117               rim_as_arr = rgrad;
00118       }
00119     else
00120       {
00121               lim_as_arr = lim.data;
00122               rim_as_arr = rim.data;
00123       }
00124     refpat = grab_16x16(lim_as_arr, w, x-7, y-7);
00125     int v = do_stereo_sparse(refpat, rim_as_arr, x, y, w, h, ftzero, max_disp, tfilter_thresh, ufilter_thresh);
00126     free(refpat);
00127     if (v < 0)
00128       return 0.0;
00129     else
00130       return v*(1.0/16.0);
00131   }
00132 
00133   // dense stereo
00134   // more accurate, but takes longer
00135   // could outfit sparse stereo with same algorithm
00136   // <frac> is set if we're passing in a stereo disparity image,
00137   //   it gives the 
00138 
00139   DenseStereo::DenseStereo(const cv::Mat& leftImg, const cv::Mat& rightImg, 
00140                            int nd, double frac)
00141   {
00142     if (nd > 0)                 // set number of disparities
00143       ndisp = nd;
00144         
00145     //    printf("Doing dense stereo with ndisp = %d\n", ndisp);
00146 
00147     lim = leftImg;
00148     rim = rightImg;
00149 
00150     // variables
00151     int xim = lim.cols;
00152     int yim = lim.rows;
00153 
00154     // clear disparity buffer - do we need to do this???
00155     imDisp = (int16_t *)MEMALIGN(xim*yim*2);
00156     memset(imDisp, 0, xim*yim*sizeof(int16_t));
00157 
00158     // check for 
00159     if (frac > 0)               // set fractional disparities, if we pass in a
00160       {                         //   disparity map
00161         fdisp = frac;           
00162         memcpy(imDisp,rim.data,xim*yim*sizeof(int16_t));
00163         return;
00164       }
00165 
00166 
00167     // some parameters
00168     int dlen   = ndisp;         // number of disparities
00169     int corr   = corrSize;      // correlation window size
00170     int tthresh = textureThresh; // texture threshold
00171     int uthresh = uniqueThresh; // uniqueness threshold, percent
00172     fdisp = 1.0/16.0;           // fixed for this algorithm
00173 
00174     // allocate buffers
00175     // TODO: make these consistent with current values
00176 
00177     buf  = (uint8_t *)MEMALIGN(yim*2*dlen*(corr+5)); // local storage for the algorithm
00178     flim = (uint8_t *)MEMALIGN(xim*yim); // feature image
00179     frim = (uint8_t *)MEMALIGN(xim*yim); // feature image
00180 
00181     // prefilter
00182     do_prefilter(lim.data, flim, xim, yim, ftzero, buf);
00183     do_prefilter(rim.data, frim, xim, yim, ftzero, buf);
00184 
00185 
00186 
00187     do_stereo(flim, frim, imDisp, NULL, xim, yim,
00188               ftzero, corr, corr, dlen, tthresh, uthresh, buf);
00189 
00190     MEMFREE(buf);
00191     MEMFREE(flim);
00192     MEMFREE(frim);
00193   }
00194 
00195   DenseStereo::~DenseStereo()
00196   {
00197     MEMFREE(imDisp);
00198   }
00199 
00200   // should look in a small area around x,y
00201   double DenseStereo::lookup_disparity(int x, int y) const
00202   {
00203     int w = lim.cols;
00204     int h = lim.rows;
00205     if (imDisp)
00206       {
00207         double v = (double)(imDisp[y*w+x]);
00208         if (v > 0.0)
00209           return v*fdisp;
00210       }
00211 
00212     return 0.0;
00213   }
00214 
00215   int DenseStereo::ndisp = 64;
00216   int DenseStereo::textureThresh = 4;
00217   int DenseStereo::uniqueThresh = 28;
00218   int DenseStereo::corrSize = 11;
00219   double DenseStereo::fdisp = 1.0/16.0;
00220 
00221 
00222 } // end namespace frame_common


frame_common
Author(s): Kurt Konolige
autogenerated on Thu Jan 2 2014 12:12:04