使用c ++和opencv计算Mat的Magnitude和Orientation时出错

时间:2014-02-19 13:29:22

标签: c++ image opencv mat

我想获得图像中所有像素值的大小和方向。这就是我到目前为止所做的事情:

cv::Sobel( dis, grad_x, dis.depth(), 1, 0, 3);     
cv::Sobel( dis, grad_y, dis.depth(), 0, 1, 3); 
Mat orientation(width, height, CV_32FC1);

#define PI 3.14159265
 for(int i = 0; i < grad_y.rows; ++i){
  for(int j= 0; j< grad_y.cols; ++j){
       orientation = atan( grad_y / grad_x ) * 180/PI ;
       magnitude= sqrt((grad_x)*(grad_x)+(grad_y)*(grad_y));
  }
   }

但是我在atan和sqrt行中出现了这个错误:

error C2665: 'atan' : none of the 3 overloads could convert all the argument type   
 math.h(108):could be 'double atan(double)
 math.h(505):float atan(float)
 math.h(553):long double atan(long double)

有谁知道这是什么问题?

提前致谢...

-----------编辑后-------------

#define PI 3.14159265
  for(int i=0; i<grad_y.rows; i++){
    for(int j=0; j<grad_y.cols; j++){
        orientation = atan( grad_y.at<float>(i,j) / grad_x.at<float>(i,j) ) * 180/PI ;
    }
}

我将sqrt更改为此但仍然出现错误:

 Mat magnitude(m_pmdDevice->GetY(), m_pmdDevice->GetX(), CV_32FC1);
    Mat gradAdd(m_pmdDevice->GetY(), m_pmdDevice->GetX(), CV_32FC1);
    grad_x = grad_x.mul(grad_x);
    grad_y = grad_y.mul(grad_y);
    cv::add(grad_x, grad_y, gradAdd);
    magnitude = sqrt(gradAdd);

3 个答案:

答案 0 :(得分:1)

atan应该得到数字(double,float或long),但是你提供矩阵。你应该使用

orientation = atan( grad_y.at<float>(i,j) / grad_x.at<float>(i,j) ) * 180/PI ;

我在我的例子中写了'浮动',因为我不知道你实际使用的是什么类型。如有必要,请更换。

sqrt中的同样问题。

编辑(编辑问题后):

您正在以错误的方式使用sqrt。见其documentation。它应该是:

sqrt(gradAdd, magnitude);

更好的方法是使用函数magnitude而不是所有的乘法和平方根:

magnitude(grad_x, grad_y, magnit);

另外,我建议你不要给作为OpenCV功能的矩阵命名。这会造成混乱。

答案 1 :(得分:0)

问题出在以下几行:

orientation = atan( grad_y / grad_x ) * 180/PI ;

因为Orientation是Mat类型并且应该包含float值(因为你已经将它声明为CV_32FC1)所以,你不能将值直接放在其中。你应该这样做:

 orientation.at<float>(i,j) = (float)atan( grad_y / grad_x ) * 180/PI ;

PS:只需要一次,如何在Matrix中添加单个值

答案 2 :(得分:0)

使用followinf代码进行元素计算以获得方向和幅度。如果您想使用上述答案中定义的函数使用量

     cv::Sobel( dis, grad_x, CV_32F, 1, 0, 3);     
     cv::Sobel( dis, grad_y, CV_32F, 0, 1, 3); 
     Mat orientation(width, height, CV_32FC1);
     Mat magnitude(width, height, CV_32FC1);
     for(int i = 0; i < grad_y.rows; ++i)
     for(int j= 0; j< grad_y.cols; ++j)
     {
      orientation.at<float>(i,j) = atan2(grad_y.at<float>(i,j),grad_x.at<float>(i,j) ) * 180/PI ;
       magnitude.at<float>(i,j)= sqrt(grad_x.at<float>(i,j)*grad_x.at<float>(i,j)+grad_y.at<float>(i,j)*grad_y.at<float>(i,j));
      }

请查看您是否将矩阵定义为CV_8UC1,然后将sqrt的类型转换为float / double,因为它仅定义为float / double而不是整数