Access to the multichannel opencv element

I am trying to learn how to use openCV new C ++ interface.

How to access the elements of a multi-channel matrix. eg:

Mat myMat(size(3, 3), CV_32FC2); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { //myMat_at_(i,j) = (i,j); } } 

What is the easiest way to do this? Something like cvSet2D old interface
What is the most effective way? Similar to using direct pointers in the old interface.

thank

+48
c ++ image image-processing opencv
Dec 01 '09 at 8:35
source share
5 answers
 typedef struct elem_ { float f1; float f2; } elem; elem data[9] = { 0.0f }; CvMat mat = cvMat(3, 3, CV_32FC2, data ); float f1 = CV_MAT_ELEM(mat, elem, row, col).f1; float f2 = CV_MAT_ELEM(mat, elem, row, col).f2; CV_MAT_ELEM(mat, elem, row, col).f1 = 1212.0f; CV_MAT_ELEM(mat, elem, row, col).f2 = 326.0f; 

Update: for OpenCV2.0

1. select one type to represent the item

Mat (or CvMat) has 3 dimensions: row, col, channel.
We can access one element (or pixel) in the matrix by specifying a row and a column.

CV_32FC2 means the item has a 32-bit floating-point value with two channels.
Thus, the element in the above code is a valid representation of CV_32FC2 .

You can use other views that you like. For example:

 typedef struct elem_ { float val[2]; } elem; typedef struct elem_ { float x;float y; } elem; 

OpenCV2.0 adds some new types to represent an element in a matrix, for example:

 template<typename _Tp, int cn> class CV_EXPORTS Vec // cxcore.hpp (208) 

So we can use Vec<float,2> to represent CV_32FC2 or use:

 typedef Vec<float, 2> Vec2f; // cxcore.hpp (254) 

Check out the source code to get more of the type that your element can represent.
Here we use Vec2f

2. access to the item

The easiest and most efficient way to access an element in the Mat class is Mat :: at.
It has 4 overloads:

 template<typename _Tp> _Tp& at(int y, int x); // cxcore.hpp (868) template<typename _Tp> const _Tp& at(int y, int x) const; // cxcore.hpp (870) template<typename _Tp> _Tp& at(Point pt); // cxcore.hpp (869) template<typename _Tp> const _Tp& at(Point pt) const; // cxcore.hpp (871) // defineded in cxmat.hpp (454-468) // we can access the element like this : Mat m( Size(3,3) , CV_32FC2 ); Vec2f& elem = m.at<Vec2f>( row , col ); // or m.at<Vec2f>( Point(col,row) ); elem[0] = 1212.0f; elem[1] = 326.0f; float c1 = m.at<Vec2f>( row , col )[0]; // or m.at<Vec2f>( Point(col,row) ); float c2 = m.at<Vec2f>( row , col )[1]; m.at<Vec2f>( row, col )[0] = 1986.0f; m.at<Vec2f>( row, col )[1] = 326.0f; 

3. interact with the old interface

Mat provides 2 conversion functions:

 // converts header to CvMat; no data is copied // cxcore.hpp (829) operator CvMat() const; // defined in cxmat.hpp // converts header to IplImage; no data is copied operator IplImage() const; // we can interact a Mat object with old interface : Mat new_matrix( ... ); CvMat old_matrix = new_matrix; // be careful about its lifetime CV_MAT_ELEM(old_mat, elem, row, col).f1 = 1212.0f; 
+59
Dec 02 '09 at 23:17
source share

Vic, you should use Vec3b instead of Vec3i:

 for (int i=0; i<image.rows; i++) { for (int j=0; j<image.cols; j++) { if (someArray[i][j] == 0) { image.at<Vec3b>(i,j)[0] = 0; image.at<Vec3b>(i,j)[1] = 0; image.at<Vec3b>(i,j)[2] = 0; } } } 
+18
Jun 09 '10 at 19:50
source share

You can directly access the underlying data array:

 Mat myMat(size(3, 3), CV_32FC2); myMat.ptr<float>(y)[2*x]; // first channel myMat.ptr<float>(y)[2*x+1]; // second channel 
+6
Jan 27 '12 at 12:23
source share

it depends on the Mat data type you use if it is numeric, for example CV_32FC1 you can use:

 myMat.at<float>(i, j) 

if it is a uchar type then you can access the element with

 (symb.at<Vec3b>(i, j)).val[k] 

where k is the channel, i.e. 0 for grayscale images and 3 for color

+1
Oct 13 '14 at 1:50
source share

The best way to access a multichannel array using C ++ api is to create a pointer to a specific string using the ptr method.

For example:

type elem = matrix.ptr<type>(i)[N~c~*j+c]

where

  • type : data type (float, int, char ect ..)
  • i : the line you are interested in
  • Nc : number of channels
  • j : column of interest to you
  • c : column of interest to you (0-3)

For information on another c-> C ++ conversion, check out this link: Source

0
Aug 08 '15 at 9:57
source share



All Articles