1

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.

2 Answers 2

2

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); } 
Sign up to request clarification or add additional context in comments.

4 Comments

Great! That fixes it. Could you explain why constexpr auto would be better than using #define?
Also, do you know why it does work using int test = FLOW_TYPE; as a local variable?
@WouterFlorijn Because it expands to int test = CV_32FC3;; with double semicolon, but that's not an error. cv::Mat flow = cv::Mat(frame1.rows, frame1.cols, CV_32FC3;); is instead an error (note the semicolon after CV_32FC3)
a define is bad because it rawly replace things. constexpr auto FLOW_TYPE = CV_32FC3; instead define a new constant known at compile time. In this case is harder make mistakes
2

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.