【发布时间】:2014-05-20 12:59:37
【问题描述】:
我有一个客户端/服务器应用程序,我的服务器管理 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 会使所有崩溃。我正在使用更新的 VS9 的最后一个 OpenCV 库构建。还与 thrift apache、pcl、eigen、vtk 和 boost 相关联。 bm/sgbm 值由客户端控制并且是正确的,我在调试/发布中没有任何错误。 可以是什么?为什么一个有效而另一个使整个应用程序崩溃?为什么只是在没有调试的情况下发布?
【问题讨论】: