opencv - What are the different ways of constructing cv::Mat? -




opencv version 3.2.0

i reading bradski , trying make different cv::mat constructors - single channel. can please tell, why constructors not work?

float data1[6] = {1,2,3,4,5,6}; float data2[6] = {10,20,30,40,50,60}; float data3[6] = {100,200,300,400,500,600};  cv::mat mat1(3,4,cv_32fc1); //ok cv::mat mat2(3,4,cv_32fc1,cv::scalar(33.3)); //ok cv::mat mat3(3,4,cv_32fc1,data1,sizeof(float)); //ok cv::mat mat4(cv::size(3,4),cv_32fc1); //ok cv::mat mat5(cv::size(3,4),cv_32fc1,cv::scalar(66.6)); //ok cv::mat mat6(cv::size(3,4),cv_32fc1,data2,sizeof(float)); //ok int sz[] = {8, 8, 8}; cv::mat bigcube1(3, sz, cv_32fc1); // ok cv::mat bigcube2(3, sz, cv_32fc1, cv::scalar::all(99)); // ok  cv::mat bigcube3(3, sz, cv_32fc1, data3, 4); // not ok, how initialise 3d data? std::cout << mat1 << std::endl << mat2 << std::endl << mat3 << std::endl << mat4 << std::endl << mat5 << std::endl << mat6 << std::endl; // ok                                                                    std::cout << bigcube1.at<float>(10,10,10)  << std::endl << bigcube2.at<float>(10,10,10) << std::endl; // ok  cv::mat img_rgb = cv::imread("lena.jpg", cv_load_image_color); std::vector<cv::range> ranges(3, cv::range(2,3));  cv::mat roirange( img_rgb, cv::range(100, 300), cv::range(0, 512)); //ok cv::mat roirect( img_rgb, cv::rect(0,100,512,200)); // ok cv::mat roirangemultiple( bigcube1, ranges); // ok  cv::namedwindow("range", cv_window_autosize); imshow("range", roirange);  // ok cv::namedwindow("rect", cv_window_autosize); imshow("rect", roirect); // ok std::cout << roirangemultiple.at<float>(0,1,1); // not ok. expecting float value answer cv::waitkey(0); 

the corresponding answers are:

[4.6634629e-10, 0, 0, 0;  0, 0, 0, 0;  127.62516, 2.8025969e-45, 0, 0]  [33.299999, 33.299999, 33.299999, 33.299999;  33.299999, 33.299999, 33.299999, 33.299999;  33.299999, 33.299999, 33.299999, 33.299999]  [1, 2, 3, 4;  2, 3, 4, 5;  3, 4, 5, 6]  [0, 0, 0;  0, 0, 0;  0, 0, 0;  0, 0, 0]  [66.599998, 66.599998, 66.599998;  66.599998, 66.599998, 66.599998;  66.599998, 66.599998, 66.599998;  66.599998, 66.599998, 66.599998]  [10, 20, 30;  20, 30, 40;  30, 40, 50;  40, 50, 60]  0  // bigcube1  99 // bigcube2 

and corresponding answers lena.jpg cropped version range , rect. dont know how use ranges though.

multiple issues.

cv::mat mat3(3,4,cv_32fc1,data1,sizeof(float)); 

this crash in debug mode, failing an assertion. though not in documentation, step size must @ least length of row (i.e. no overlap allowed).

the correct code scenario like.

float data1[12] = { 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 }; cv::mat mat3(3, 4, cv_32fc1, data1, 4 * sizeof(float)); 

cv::mat mat6(cv::size(3,4),cv_32fc1,data2,sizeof(float)); 

similar situation in previous case. note produces differently shaped array -- previous 3 rows, 4 columns, 1 has 4 rows , 3 columns (see docs of cv::size).

float data2[12] = { 10, 20, 30, 40, 20, 30, 40, 50, 30, 40, 50, 60 }; cv::mat mat6(cv::size(3, 4), cv_32fc1, data2, 3 * sizeof(float)); 

cv::mat bigcube1(3, sz, cv_8uc1); std::cout << bigcube1 << std::endl; 

formatting of arrays more 2 dimensions not supported.

you can test array correctly created manually printing values:

for (auto const& v : cv::mat1b(bigcube2)) {     std::cout << uint(v) << " "; } std::cout << "\n"; 

cv::mat bigcube3(3, sz, cv_32fc1, data3, 4); 

the problem here last parameter. the docs

cv::mat::mat(int ndims,     const int *   sizes,     int type,     void * data,     const size_t * steps = 0      ) 

steps - array of ndims-1 steps in case of multi-dimensional array (the last step set element size). if not specified, matrix assumed continuous.

  • you're not passing array of steps last parameter (only single integer)
  • you don't pass enough data
  • and rows again overlap.

one way like

float data3[8 * 8 * 8]; // populate data sequence 0..511 std::iota(std::begin(data3), std::end(data3), 0.0f);  int sz[] = { 8, 8, 8 }; size_t steps[] = { 8 * 8 * sizeof(float), 8 * sizeof(float) }; cv::mat bigcube3(3, sz, cv_32fc1, data3, steps); 

cv::mat bigcube1(3, sz, cv_8uc1); // ... std::cout << roirangemultiple.at<float>(0,1,1); // not ok. expecting float value answer 

the data type cv_8uc1, each element unsigned char. means shouldn't extracting float values it. expectation incorrect. (now see changed code in question).

also, note cv::range "start inclusive left boundary of range , end exclusive right boundary of range". since extract cv::range(2,3) in each axis, resulting mat 1 x 1 x 1. hence, you're accessing elements out of range (again, trigger debug mode assertion).

std::cout << roirangemultiple.at<unsigned char>(0,0,0); 

after change have correct type. notice never initialize bigcube1. 0.0f result, print 0. can try yourself, execute std::cout << 0.0f; , see.





wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -