Attention! This forum will be made read-only by Dec-20. Please migrate to https://forum.opencv.org. Most of existing active users should've received invitation by e-mail.
Ask Your Question
1

push back element to the column of cv::Mat

asked 2013-11-08 13:44:42 -0500

stereomatching gravatar image

updated 2013-11-09 12:09:54 -0500

How could I push back the floating point value to the column of cv::Mat?

cv::Mat_<float> A;
A.push_back(0);
A.push_back(1);
A.push_back(2);
A.push_back(3);

Suppose I want to make the matrix become 2 rows 2 cols like this [0, 1; 2, 3].How could I push the value into the column of A with type "float"?

Edit : exception thrown

A = A.reshape(1,2); //this line would crash in openCV 2.4.5

cv::Mat_<float> B = A.reshape(1, 2); //ok, wouldn't crash, but the buffer are different
std::cout<<(B.data == A.data)<<std::endl; // answer is 0

Exception : "Assertion failed (!fixedType() || ((Mat)obj)->type() == mtype) in create, file /Users/yyyy/Downloads/opencv-2.4.5/modules/core/src/matrix.cpp, line 1345"*

Don't know where is the error occur, should I treat this as a bug and report it?

Edit 2 : unsafe codes?

I found something interesting, in the class Mat there are a flag

/*! includes several bit-fields:
     - the magic signature
     - continuity flag
     - depth
     - number of channels
 */
int flags;

The flags is int, that means the behavior of the sign bit may not work as the programmer expect. When we call reshape, the Mat will do some operation on the flag

hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT);

And the function fixedType() and type() use the flags to check the type of Mat

core/include/opencv2/core/mat.inl.hpp

inline
int Mat::type() const
{
  return CV_MAT_TYPE(flags);
}

modules/core/src/matrix.cpp

bool _OutputArray::fixedType() const
{
    return (flags & FIXED_TYPE) == FIXED_TYPE;
}
edit retag flag offensive close merge delete

Comments

1

you could just call A = A.reshape(1,2); (that's not copying data, just adjusting rows/cols)

berak gravatar imageberak ( 2013-11-08 13:56:23 -0500 )edit

Thanks, I tried it but A = A.reshape(1, 2) would throw exception; cv::Mat_<float> B = A.reshape(1, 2) wouldn't(memory will reallocate).If I change cv::Mat_<float> to cv::Mat, A = A.reshape(1, 2) is work too.The error message is "Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in create, file /Users/yyyy/Downloads/opencv-2.4.5/modules/core/src/matrix.cpp, line 1345"

stereomatching gravatar imagestereomatching ( 2013-11-08 14:50:44 -0500 )edit

interesting ( sorry, i did not actually test it )

funny thing is, that Mat and Mat_<float> behave differently here, with plain Mat it just works, Mat_<float> throws the mentionend exception.

and it's about the type, not the reshaped rows/cols. (what?)

also, why do you think, Mat B=A.reshape(1,2) is reallocating ?

berak gravatar imageberak ( 2013-11-08 15:13:38 -0500 )edit

wait, we have not solved, why Mat_<float> is behaving different from plain Mat, or did i miss something ?

(that's definitely worth inquiring, isn't it ?)

Mat_<float> m = ...

Mat_<float> m2 = m.reshape(1,2); // works

m = m.reshape(1,2); // above problem, if m is Mat_<float>

no problem, again, if it's just plain Mat. bug or something ?

berak gravatar imageberak ( 2013-11-08 17:41:36 -0500 )edit

what's puzzling me most here, - why is it throwing a type exception ?

berak gravatar imageberak ( 2013-11-08 17:49:00 -0500 )edit

Don't know, maybe the function Mat_ operator=(const Mat& m); has some problem when transform, finding the location of the source codes, please tell me where is it if you know, thanks.

stereomatching gravatar imagestereomatching ( 2013-11-09 01:40:29 -0500 )edit

I'm having the same problem. Did this ever get resolved?

Seanny123 gravatar imageSeanny123 ( 2014-04-01 05:09:46 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
4

answered 2014-07-16 17:04:47 -0500

camille gravatar image

Hi,

I looked into the bug and reported my analysis there: http://www.code.opencv.org/issues/3381

In this case the following lines would work : Mat_<float> A; A.push_back(0.0f);//instead of A.push_back(0); A.push_back(1.0f); A.push_back(3.0f); A.push_back(4.0f); A = A.reshape(1, 2);

I am about to submit a bug-fix.

Camille

edit flag offensive delete link more

Comments

1

good boy ;)

berak gravatar imageberak ( 2014-07-16 23:20:57 -0500 )edit
Login/Signup to Answer

Question Tools

Stats

Asked: 2013-11-08 13:44:42 -0500

Seen: 9,396 times

Last updated: Jul 16 '14