Search code examples
c++opencvmatrixopencv3.0magnitude

Trying to find Magnitude of Mat image


I'm trying to learn OpenCV (Using version 3.0.0). Right now I'm trying to see what the point operatioins do to various images, everything is going fine until I tried to do the magnitude operation, which requires inputs be in the form of

magnitude(InputArray x, InputArray y, OutputArray magnitude)

It also describes that x and y should be floating-point arrays of x/y-coordinates of the vectors and also the same size.

I've tried making a Vector of Mat's and splitting up the input image into these vectors and then doing the magnitude operator on them, but this didn't work. So I think I need to pass the arguments as columns and rows, but now I'm getting the error

    OpenCV Error: Assertion failed (src1.size() == src2.size() && type == src2.type() && (depth == CV_32F || depth == CV_64F)) in magnitude, file /home/<user>/opencv-3.0.0-beta/modules/core/src/mathfuncs.cpp, line 521
    terminate called after throwing an instance of 'cv::Exception'
      what():  /home/<user>/opencv-3.0.0-beta/modules/core/src/mathfuncs.cpp:521: error: (-215) src1.size() == src2.size() && type == src2.type() && (depth == CV_32F || depth == CV_64F) in function magnitude

Aborted (core dumped)

And I'm not sure why, because I am clearly converting the input Mats to CV_64F types. Am I using the magnitude function wrong? Or just passing it the wrong data?

void Magnitude(Mat img, Mat out)
{

    img.convertTo(img, CV_64F);
    out.convertTo(out, CV_64F); 

    for(int i = 0 ; i < img.rows ; i ++)
        for(int j = 0 ; j < img.cols ; j++)
            cv::magnitude(img.row(i), img.col(j), out.at<cv::Vec2f>(i,j));

    cv::normalize(out,out,0,255,cv::NORM_MINMAX);
    cv::convertScaleAbs(out,out);
    cv::imshow("Magnitude", out);

    waitKey();
}

Solution

  • void magnitude(InputArray x, InputArray y, OutputArray magnitude)
    

    where x, y and magnitude must have the same size. In your case it means that your image have to be quadratic. Is it right?

    A sample usage:

    cv::Sobel(img, gx, img.depth(), 1, 0, 3);     
    cv::Sobel(img, gy, img.depth(), 0, 1, 3); 
    
    cv::Mat mag(gx.size(), gx.type());
    cv::magnitude(gx, gy, mag);