“断言”功能:奇怪的行为

萨拉赫鲍尔

我正在使用Qt Creator在C ++的Windows 7上进行开发。我也使用库OpenCV

我遇到了一个奇怪的问题assert我开发了一个函数,可以对图像进行线性变换以获得更好的对比度,并可以指定我们要处理的图像区域(x1,x2,y1,y2)以及公差(Tolmin和Tolmax):我们要忽略的直方图的百分位数。

我需要确保:

  • 图片为16位灰度(img.type()= CV_16U && img.channels()= 1)
  • 区域坐标正确(正,请勿超过图像尺寸...)
  • Tolmin,Tolmax正且Tolmin + Tolmax!= 1(如果Tolmin + Tolmax = 1,则除以0)

我用的功能 assert

我的代码如下:

void equalizeHist_16U_linear(Mat &img, float Tolmin, float Tolmax, int x1, int x2, int y1, int y2)
{
    assert(img.channels() == 1);
    assert(img.type() == CV_16U);
    assert(x1>=0 && y1>=0 && x2>=x1 && y2>=y1);
    assert(y2<img.rows && x2<img.cols);
    assert(Tolmin>0 && Tolmax>0);
    assert(Tolmin+Tolmax != 1.0);

    ## code ##
    ...

}

前五个assert效果很好,但最后一个效果assert(Tolmin+Tolmax != 1.0)不佳。即使在时Tolmin+Tolmax=1,assert也不停止执行,因此程序崩溃(被0除)。可以肯定的是,我Tolmin+Tolmaxassert通话之前进行了打印

void equalizeHist_16U_linear(Mat &img, float Tolmin, float Tolmax, int x1, int x2, int y1, int y2)
{
    cout << endl << "Tolmin+Tolmax = " << Tolmin+Tolmax << endl;

    assert(img.channels() == 1);
    assert(img.type() == CV_16U);
    assert(x1>=0 && y1>=0 && x2>=x1 && y2>=y1);
    assert(y2<img.rows && x2<img.cols);
    assert(Tolmin>0 && Tolmax>0);
    assert(Tolmin+Tolmax != 1.0);

    ## code ##
    ...

}

显示“ Tolmin + Tolmax = 1”,这时assert停止了程序的执行!

这怎么可能 ?为什么显示Tolmin+Tolmaxmakeassert起作用?

我试图添加以下内容:

void equalizeHist_16U_linear(Mat &img, float Tolmin, float Tolmax, int x1, int x2, int y1, int y2)
{
    float sum = Tolmin+Tolmax;

    assert(img.channels() == 1);
    assert(img.type() == CV_16U);
    assert(x1>=0 && y1>=0 && x2>=x1 && y2>=y1);
    assert(y2<img.rows && x2<img.cols);
    assert(Tolmin>0 && Tolmax>0);*/
    assert(sum != 1.0);

    ## code ##
    ...

}

但这也不起作用。

突触

我的猜测是您的代码中使用了一个值(如Tolmin或Tolmax),而该值无法以机器的数字格式表示。我什么意思 好了,您可以轻松地想到哪些数字计算机无法完全按原样存储它们。计算机必须以有限数字的二进制格式存储数字,因此某些数字将不能完全按原样存储。这样想,我们可以想到数字(2/3)对吗?但是当我们必须用有限位数的十进制格式表示此数字时,我们必须将其舍入为:0.66666667,因此我们无法准确地按原样写入此数字。这种情况也可以在机器中产生,例如,我们不能以二进制格式将数字0.2存储在机器中,因为其代表二进制数是无限的,机器会将这些数字四舍五入到可以存储的最接近的数字。在您的情况下,您正在将转换后的二进制数与绝对值(1.0)进行比较,并且逻辑上它们即使彼此非常接近也不相同。所以我的猜测是Tolmin和Tolmax的总和将非常接近1.0,但不完全是1.0。那么解决方案是什么?您应该检查sum是否已超过1.0的任意间隔。像这样:

assert(abs(sum - 1.0) > 0.0001)

更新:我无法在使用gcc和MSC ++进行打印时重现您报告的行为,因此,我只能做一个较弱的猜测。生成代码时,编译器将在优化阶段对其进行修改。您要Tolmin+Tolmax在两个位置进行计算,首先在cout中,其次在assert中,因此编译器将推断出该计算可以执行一次,然后再使用它的结果。当cout更改您要显示的数字时,该值非常接近1,它将被四舍五入并获得确切的值1,然后结果将在assert中重用。是否可以,我无法确认,因为我无法重现报告的行为。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

“断言”功能:奇怪的行为

来自分类Dev

检查Alloy中的断言时的奇怪行为

来自分类Dev

奇怪的窗口功能行为

来自分类Dev

“读取”系统功能的奇怪行为

来自分类Dev

Ruby:奇怪的字符串比较断言行为

来自分类Dev

基本功能的奇怪行为

来自分类Dev

Coffeescript和护照:奇怪的行为,附加功能

来自分类Dev

奇怪的行为存储功能导致OCaml

来自分类Dev

带有替换功能的JSON.stringify中的奇怪行为

来自分类Dev

同时执行队列中对象的功能时的奇怪行为

来自分类Dev

奇怪的SQLite行为-非功能性UPDATE SQLite方法

来自分类Dev

更新到Swift 3后奇怪的转义功能行为

来自分类Dev

WPF 功能区绑定到 ViewModel HierarchicalDataTemplate 奇怪的行为

来自分类Dev

奇怪的行为

来自分类Dev

奇怪的行为

来自分类Dev

奇怪的行为

来自分类Dev

预测行为的奇怪行为

来自分类Dev

从列表中随机选择功能并测试其功能时的奇怪行为

来自分类Dev

Modelica断言的意外行为

来自分类Dev

呼吁java.lang.reflect.Proxy对象扩展功能时科特林奇怪的行为

来自分类Dev

使用c ++ 20概念和模板化类的奇怪的GCC(树干)行为:是Bug还是功能?

来自分类Dev

具有数组和结构的四分卫评级功能的行为很奇怪

来自分类Dev

React 多个复选框的行为很奇怪,在状态中添加了确认和取消功能

来自分类Dev

奇怪的addEventListener行为

来自分类Dev

MATLAB subs():奇怪的行为

来自分类Dev

右移位的奇怪行为

来自分类Dev

奇怪的约束行为

来自分类Dev

IronPython奇怪的行为

来自分类Dev

Java重载的奇怪行为