Go to the documentation of this file.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 "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
00067
00068
00069 CStereoVision::CStereoVision()
00070 {
00071 }
00072
00073 CStereoVision::~CStereoVision()
00074 {
00075 }
00076
00077
00078
00079
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
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
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
00200
00201 _ProcessFast(pLeftImage, pRightImage, pDepthImage, nWindowSize, d1, d2, d_step, nErrorThreshold);
00202
00203
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
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
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
00245 for (d = d1; d != d2; d += d_step)
00246 {
00247 int c, r;
00248
00249
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;
00271 unsigned char *pDepthHelper = pDepthImageData + (nWindowSize - 1) * width;
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
00279
00280 if (V_SUM[c] < pMinHelper[c])
00281 {
00282 pMinHelper[c] = V_SUM[c];
00283 pDepthHelper[c] = abs(d);
00284 }
00285
00286 }
00287
00288
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];
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
00307
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
00315
00316
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
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