Wouter Florijn
Wouter Florijn

Reputation: 2941

OpenCV #define type for Mat

I'm using C++ and OpenCV. Now I want to define a certain Mat type (such as CV_32FC3) to be used by lots of Mats in my code.

To achieve this, I tried:

#define FLOW_TYPE CV_32FC3;

cv::Mat BaoOpticalFlow::initialize(cv::Mat & frame1, cv::Mat & frame2)
{
    cv::Mat flow = cv::Mat(frame1.rows, frame1.cols, FLOW_TYPE);
}

However, this causes errors

expected a ')'

expected an expression

Then I tried,

#define FLOW_TYPE CV_32FC3;

cv::Mat BaoOpticalFlow::initialize(cv::Mat & frame1, cv::Mat & frame2)
{
    int test = FLOW_TYPE;
    cv::Mat flow = cv::Mat(frame1.rows, frame1.cols, test);
}

Which works, but is ugly in my opinion.

I don't really understand why or how this works, and why the first snippet causes errors. I'm not a C++ expert, so any help is appreciated.

Upvotes: 1

Views: 907

Answers (2)

Miki
Miki

Reputation: 41765

You have an error because it expands to

cv::Mat flow = cv::Mat(frame1.rows, frame1.cols, CV_32FC3;); 

which causes the error (note the semicolon after CV_32FC3). With the local variable instead it expands to:

int test = CV_32FC3;; 

with double semicolon, but that's not an error.

You can correct this defining without the semicolon:

#define FLOW_TYPE CV_32FC3

It would probably easier to directly define which kind of matrix you want to use, and use Mat_<Tp> for easier access (you don't need to use .at<Tp>(...) to access elements, but just the parentheses):

using FlowMat = cv::Mat3f;

cv::Mat BaoOpticalFlow::initialize(cv::Mat & frame1, cv::Mat & frame2)
{
    FlowMat flow(frame1.rows, frame1.cols);

    // or, to zero initialize
    // FlowMat flow = FlowMat::zeros(frame1.rows, frame1.cols); 

}

Or:

using FlowType = cv::Vec3f;
using FlowMat = cv::Mat_<FlowType>;

void foo(cv::Mat& frame1, cv::Mat& frame2)
{
    FlowMat flow = FlowMat::zeros(frame1.rows, frame1.cols);

    flow(2, 3) = FlowType(1, 2, 3);
    FlowType value = flow(2, 3);

    // ...
}

Upvotes: 2

Elvis Dukaj
Elvis Dukaj

Reputation: 7368

Your mistake is in the ; at the end of the define. Your code must be:

#define FLOW_TYPE CV_32FC3

cv::Mat BaoOpticalFlow::initialize(cv::Mat & frame1, cv::Mat & frame2)
{
    cv::Mat flow = cv::Mat(frame1.rows, frame1.cols, FLOW_TYPE);
}

More nice if you remove at all the define like this:

constexpr auto FLOW_TYPE = CV_32FC3;

cv::Mat BaoOpticalFlow::initialize(cv::Mat & frame1, cv::Mat & frame2)
{
    cv::Mat flow = cv::Mat(frame1.rows, frame1.cols, FLOW_TYPE);
}

Upvotes: 2

Related Questions