目录
1 同事A的bug:imgproc/src/resize.cpp:4054: error: (-215:Assertion failed) inv_scale_x > 0 in function 'resize'
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.5.4) /home/ubuntu/build_opencv/opencv/modules/imgproc/src/resize.cpp:4054: error: (-215:Assertion failed) inv_scale_x > 0 in function 'resize'
同事A要封装一个算法SDK库,然后上面是他遇到的bug,让我帮忙看一下,这种bug我第一反应就是传入的参数不对导致判断条件不成立,然后我经过调试发现,深度学习算法的输入是224*224,然后图片的高是124,所以124/224两个整数相除结果是0,所以这里报错了,看起来挺合理的,于是我帮他修改代码如下
double fx = static_cast<double>(w) / img.rows;
double fy = static_cast<double>(h) / img.cols;
cv::resize(img, sample_resize, cv::Size(), fx, fy, cv::INTER_NEAREST);
//cv::resize(img, sample_resize, cv::Size(w, h));
这样转成double之后,相除肯定就不是零了,看起来很合理,bug也解决了,然后这件事我也就忘了,直到过了一段时间之后同事B遇到了另一个bug,然后找到我
2 同事B的bug:/modules/core/src/alloc.cpp:73:error:
(-4:Insufficient memory)Failed to allocate 24240532538988d bytes in function
'0utofMemoryError
上面同事A封装的算法SDK库最终是要放到同事B的C++引擎中使用的,然后他遇到了一个bug。

经过调试发现是崩溃在
刚开始我根本就没怀疑resize的问题,因为我早就已经把帮同事A解决的那个bug忘记了,没印象了已经,然后我还是各种调试,尝试,各种修改代码,然后发现都挺正常的,传入的参数也正常,都没能找到原因。
然后单独跑算法SDK的demo就没问题,但是把算法库放到引擎中就不行,两者输入的图片我也改成一样的了可是引擎还是报错,这时候我才开始怀疑是链接的库有问题,或者用的头文件有问题,然后ldd看了下库发现页正常。那是什么原因呀。
3 bug解决
于是我再看一遍同事A的代码,这时候我发现了之前我帮同事A修改过的resize问题,然后我去看了下resize的注释
//! @} imgproc_filter
//! @addtogroup imgproc_transform
//! @{
/** @brief Resizes an image.
The function resize resizes the image src down to or up to the specified size. Note that the
initial dst type or size are not taken into account. Instead, the size and type are derived from
the `src`,`dsize`,`fx`, and `fy`. If you want to resize src so that it fits the pre-created dst,
you may call the function as follows:
@code
// explicitly specify dsize=dst.size(); fx and fy will be computed from that.
resize(src, dst, dst.size(), 0, 0, interpolation);
@endcode
If you want to decimate the image by factor of 2 in each direction, you can call the function this
way:
@code
// specify fx and fy and let the function compute the destination image size.
resize(src, dst, Size(), 0.5, 0.5, interpolation);
@endcode
To shrink an image, it will generally look best with #INTER_AREA interpolation, whereas to
enlarge an image, it will generally look best with c#INTER_CUBIC (slow) or #INTER_LINEAR
(faster but still looks OK).
@param src input image.
@param dst output image; it has the size dsize (when it is non-zero) or the size computed from
src.size(), fx, and fy; the type of dst is the same as of src.
@param dsize output image size; if it equals zero (`None` in Python), it is computed as:
\f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f]
Either dsize or both fx and fy must be non-zero.
@param fx scale factor along the horizontal axis; when it equals 0, it is computed as
\f[\texttt{(double)dsize.width/src.cols}\f]
@param fy scale factor along the vertical axis; when it equals 0, it is computed as
\f[\texttt{(double)dsize.height/src.rows}\f]
@param interpolation interpolation method, see #InterpolationFlags
@sa warpAffine, warpPerspective, remap
*/
CV_EXPORTS_W void resize( InputArray src, OutputArray dst,
Size dsize, double fx = 0, double fy = 0,
int interpolation = INTER_LINEAR );
这里面其中有个解释是说,当fx=0或者fy=0的时候,他自动的会在前面加个double然后计算除数,可是为什么我同事A的代码会报错呢,这时候我基本上怀疑是opencv库或者头文件的问题了,于是我用了一个我自己的makefile编译,并且把代码继续改回去
// double fx = static_cast<double>(w) / img.rows;
// double fy = static_cast<double>(h) / img.cols;
// cv::resize(img, sample_resize, cv::Size(), fx, fy, cv::INTER_NEAREST);
cv::resize(img, sample_resize, cv::Size(w, h));
然后我发现放到同事B的引擎中也不报错了,好吧。然后我去检查了一下我同事A的makefile,发现他里面用的头文件路径是:/data/chw/compute_lib/include/opencv/opencv_gpu_arm
然而他用的这个根本就不是现在orin盒子上的版本,,,,原来问题在这里。
4 总结与反思
bug是解决了,但是中间其实走了很多弯路,浪费时间,
- 其实第一次帮同事A解决bug的时候我但凡要是去看一下resize函数的注释也不会这样,我当初是经验主义觉得这种报错肯定就是参数不对导致的,我直接double转一下就解决了,我应该想到opencv源码肯定早就考虑了这种情况,一个开源了这么久的代码怎么会连这点都没考虑到。
- 又或者我后来帮同事B解决bug各种尝试不行的时候,当我开始怀疑是库不会或者头文件不匹配的时候,我打开同事A的makefile从头到尾看一遍也早就解决了。
- 以后遇到bug,不要一股脑的就开始调试去解决,应该先静下来思考下原因再去做,先考虑下是不是宏观上有什么地方错了,而不是直接陷到局部代码里面。
- 还有就是就算陷到局部代码里面了,那么当调试没什么问题,找不到原因的时候,就应该考虑换一种方法了或者应该去思考其他的途径了,而不是一直在那里打断点各种调试浪费时间。