getting error in calculating the Magnitude and Orientation of a Mat Using c++ and opencv

StackOverflow https://stackoverflow.com/questions/21881950

  •  13-10-2022
  •  | 
  •  

I want to get the magnitude and orientation of all pixel values in an image. This is what I have done until now:

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));
  }
   }

but I get this error in atan and sqrt lines :

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)

does anyone know what is the problem?

Thanks in advance...

-----------After Editing-------------

#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 ;
    }
}

I changed the sqrt into this but still I get error:

 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);
有帮助吗?

解决方案

atan should get number (double, float or long), but you are providing matrix. You should use

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

I wrote 'float' in my example since I don't know what type you are actually using. Replace it if necessary.

Same problem in sqrt.

Edit (after edit of question):

You are using sqrt in the wrong way. See its documentation. It should be:

sqrt(gradAdd, magnitude);

Even better will be to use function magnitude instead of all the multiplications and square roots:

magnitude(grad_x, grad_y, magnit);

Also I recommend you not to give names to matrices that are functions of OpenCV. This will create confusion.

其他提示

the problem is in the following line:

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

Because Orientation is of Mat type and should contain float value(because you have declared it as CV_32FC1) so, you can not put the values directly in it. You should do it as following:

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

PS: Just thing once, how can you put a single value in a Matrix

Use the followinf code for element wise computation for obtaining orientation and magnitude. If you want to use a function use magnitude as defined in above answer

     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));
      }

Please see if you define your matrix as CV_8UC1 then typecast argument for sqrt as float/double as it is only defined for float/double and not for integers

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top