先貼源代碼,及問題;
// 轉換為灰度圖像
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, 1, 0, 3, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x );
// Y方向梯度 並取絕對值
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, 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范數梯度計算部分為新加,原始代碼是加權求和計算梯度;上述代碼運行出錯,錯誤信息如下:
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操作異常。
修正代碼
代碼運行正常了,ok。
另:問題總是很細小,很惹人糾結。