OpenCV计算sobel算子梯度值(2范数)(调试问题及分析)


先贴源代码,及问题;

  src =imread( " lena.jpg ");

   // 转换为灰度图像
  cvtColor( src, src_gray, CV_RGB2GRAY );

   //  创建X、Y方向梯度图像变量
  Mat grad_x, grad_y;
  Mat abs_grad_x, abs_grad_y; //  梯度绝对值

  
//  X方向梯度 并取绝对值
  Sobel( src_gray, grad_x, ddepth,  103, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_x, abs_grad_x );
   //  Y方向梯度 并取绝对值
  Sobel( src_gray, grad_y, ddepth,  013, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_y, abs_grad_y );
 
  Mat result(Size(512,512), CV_32F);
  /*
    采用cv函数计算梯度值
    
*/
  cv::pow(abs_grad_x, 2.0f,abs_grad_x);
  cv::pow(abs_grad_y, 2.0f,abs_grad_y);
  cv::add(abs_grad_x,abs_grad_y,result); //问题代码所在
  cv::pow(result, 0.5f,result); // 出错的地方

  waitKey( 0);

   return  0

 上述代码,基础部分参见opencv sobel_demo代码,2范数梯度计算部分为新加,原始代码是加权求和计算梯度;上述代码运行出错,错误信息如下:

Assertion failed (depth == CV_32F || depth == CV_64F) in pow, file /http://www.cnblogs.com/OpenCV-2.3.1/modules/core/src/mathfuncs.cpp, line 1898 terminate called after throwing an instance of 'cv :: Exception'
what():  /http://www.cnblogs.com/OpenCV-2.3.1/modules/core/src/mathfuncs.cpp:1898: error: (-215) depth == CV_32F || depth == CV_64F in function pow

 内容是指pow函数参数的类型不对,pow中指数为小数或者负数的时候要求图像类型为float或double。

但是明明上面声明result变量时,类型是CV_32F ;问题很诡异。

调试策略:为了搞清楚result变量的类型,首先在创建对象前输出了result.type()的值,结果很正确是5(即CV_32F) ;

       同时监视,代码出错时变量的类型,发现是1;

猜想,应该是出错前执行的操作改变了result变量的type;

通过排查发现,唯一设计操作result变量的代码:cv::add(abs_grad_x,abs_grad_y,result);

问题就应该在这里了。

查看手册及函数原型:

CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst,
                      InputArray mask=noArray(), int dtype=-1);

原始调用时,两个缺省值没有改变,这两个值颇有嫌疑;下面为手册中的变量说明:

mask – Optional operation mask, 8-bit single channel array, that specifies elements of the
destination array to be changed. //这个可以不关心
dtype – Optional depth of the output array. 输出图像的深度depth就是由该变量定义的。
……略

手册中提到,如果两幅原图像的深度相同的话, dtype缺省为-1,并且输出图像与原图像深度相同。(关于深度与type之间的关系,还有待深入考究)
从而导致执行add操作后,result的type值就变化了,导致后面执行pow操作异常。

修正代码

cv :: add(abs_grad_x,abs_grad_y,result,noArray(),CV_32F);

代码运行正常了,ok。

另:问题总是很细小,很惹人纠结。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM