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