StereoBM OpenCV在没有调试的情况下发布了错误的分配

StereoBM OpenCV bad allocation in release without debugging

本文关键字:错误 分配 情况下 StereoBM 调试 OpenCV      更新时间:2023-10-16

我有一个客户端/服务器应用程序,我的服务器管理opencv库来做例如视差映射,应用程序与stereoSGBM工作得很好,但与stereoBM我随机崩溃与ctrl + f5释放,所以启动它没有调试。

崩溃是随机的,使用try/catch有时我可以得到糟糕的分配内存,未能分配1k字节。相反,使用调用堆栈,我无法捕获任何相关的东西,因为崩溃并不总是在同一点,有时是在imgread,有时是malloc, free a mat.release,所以每次都是不同的,但总是以某种方式涉及内存。

代码很简单:

void disparity_mapping(std::vector<std::string> & _return, const StereoBmValue& BmValue, const ClientShowSelection& clientShowSelection, const std::string& filenameL, const std::string& filenameR)
{
int ch;
alg = BmValue.algorithmSelection;
if((filenameL == "0" || filenameR == "0"))
_return.push_back("0");
if((filenameL != "0" && filenameR != "0"))
{
  imgL = imread(filenameL , CV_LOAD_IMAGE_GRAYSCALE );
  imgR = imread(filenameR, CV_LOAD_IMAGE_GRAYSCALE );
  _return.push_back("1");
  ch = imgL.channels();
  setAlgValue(BmValue, methodSelection, ch); //Setting the value for StereoBM or SGBM
  disp = calculateDisparity(imgL, imgR, alg); //calculating disparity
  normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
  string matAsStringL(imgL.begin<unsigned char>(), imgL.end<unsigned char>());
  _return.push_back(matAsStringL);
  string matAsStringR(imgR.begin<unsigned char>(), imgR.end<unsigned char>());
  _return.push_back(matAsStringR);
  string matAsStringD(disp8.begin<unsigned char>(), disp8.end<unsigned char>());
  _return.push_back(matAsStringD);
}

调用的两个函数:

void setAlgValue(const StereoBmValue BmValue, int methodSelection, int ch)
{   
    if (initDisp)
        initDisparity(methodSelection); //inizializing bm.init(...) and find remap informations from steroRect, etc.
    //Select  0 == StereoSGBM, 1 == StereoBM
    int alg = BmValue.algorithmSelection;
    //storing alg value.
    stereoValue.minDisparity = BmValue.minDisparity;
    stereoValue.disp12MaxDiff = BmValue.disp12MaxDiff;
    stereoValue.SADWindowSize = BmValue.SADWindowSize;
    stereoValue.textureThreshold = BmValue.textureThreshold;
    stereoValue.uniquenessRatio = BmValue.uniquenessRatio;
    stereoValue.numberOfDisparities = BmValue.numberOfDisparities;
    stereoValue.preFilterCap = BmValue.preFilterCap;
    stereoValue.speckleWindowSize = BmValue.speckleWindowSize;
    stereoValue.speckleRange = BmValue.speckleRange;
    stereoValue.preFilterSize = BmValue.preFilterSize;
if (alg == 1) //set of the values in the bm state
{
    bm.state->roi1 = roi1;
    bm.state->roi2 = roi2;
    bm.state->preFilterCap = stereoValue.preFilterCap;
    bm.state->SADWindowSize = stereoValue.SADWindowSize;
    bm.state->minDisparity = stereoValue.minDisparity;
    bm.state->numberOfDisparities = stereoValue.numberOfDisparities;
    bm.state->textureThreshold = stereoValue.textureThreshold;
    bm.state->uniquenessRatio = stereoValue.uniquenessRatio;
    bm.state->speckleWindowSize = stereoValue.speckleWindowSize;
    bm.state->speckleRange = stereoValue.speckleRange;
    bm.state->disp12MaxDiff = stereoValue.disp12MaxDiff;
    bm.state->preFilterSize = stereoValue.preFilterSize;
}

else if(alg == 0) //same for SGBM
{
    sgbm.P1 = 8*ch*sgbm.SADWindowSize*sgbm.SADWindowSize;
    sgbm.P2 = 32*ch*sgbm.SADWindowSize*sgbm.SADWindowSize;
    sgbm.preFilterCap = stereoValue.preFilterCap;
    sgbm.SADWindowSize = stereoValue.SADWindowSize;
    sgbm.minDisparity = stereoValue.minDisparity;
    sgbm.numberOfDisparities = stereoValue.numberOfDisparities;
    sgbm.uniquenessRatio = stereoValue.uniquenessRatio;
    sgbm.speckleWindowSize = stereoValue.speckleWindowSize;
    sgbm.speckleRange = stereoValue.speckleRange;
    sgbm.disp12MaxDiff = stereoValue.disp12MaxDiff;
}
}

和另一个:

Mat calculateDisparity(Mat& imgL, Mat& imgR,  int alg)
{
    Mat disparity;
//remap for rectification
remap(imgL, imgL, map11, map12, INTER_LINEAR,BORDER_CONSTANT, Scalar());
remap(imgR, imgR, map21, map22, INTER_LINEAR,BORDER_CONSTANT, Scalar());
//disp
if (alg == 1)  
 bm( imgL , imgR , disparity);
else if (alg == 0)
 sgbm(imgL, imgR, disparity);
return disparity;
}

正如你所看到的,代码非常简单,但是使用bm会导致崩溃。我正在使用最新的OpenCV库构建VS9更新。也与节俭apache, pcl, eigen, vtk和boost有关。bm/sgbm的值是由客户端控制的,是正确的,我没有得到任何错误的调试/发布与调试。可能是什么?为什么一个工作正常,而另一个使整个应用程序崩溃?为什么只在发布版中没有调试?

我也有同样的问题,只是发现bm的值很高。state->textureThreshold会崩溃。