opencv multi channel element access
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. choose one type to represent the element
Mat (or CvMat) has 3 dimensions: row, col, channel.
We can access one element (or pixel) in the matrix by specifying the row and col.
CV_32FC2
means the element is 32bit floating point value with 2 channels.
So elem in above code is one acceptable representation of CV_32FC2
.
You can use other representations 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 the element in the matrix,like :
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)
See the source code to get more type that can represent your element.
Here we use Vec2f
2. access the element
The easiest and efficiant way to access the 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 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;
Accessing elements in a multi-channel OpenCV Mat
The first element of a cv::Mat
is always at (0, 0)
, so just correct cv::Vec3f elem = rgb_m.at<cv::Vec3f>(1, 1);
by cv::Vec3f elem = rgb_m.at<cv::Vec3f>(0, 0);
and cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(1, 1);
by cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(0, 0);
opencv matrix multi channel access and fill
As mentioned earlier, pixels next to the high-intensity pixel take non-zero values after JPG-compression because JPEG is a lossy algorithm. In fact, JPEG-compression discards information precisely in image regions with strong gradient.
As for your second question: your pixels are blue because of an Opencv quirk: color channels are not stored in R, G, B order, but in B, G, R order:
For color images, the channel ordering is normally Blue, Green, Red
Source: http://docs.opencv.org/modules/core/doc/drawing_functions.html?highlight=green
(this is one of those things that make life miserable for the Opencv programmer)
how to access nth channel of a Mat in opencv?
Let's say n = 10
and we want to access 4th
channel of pixel (i, j)
. Here's a simple example:
typedef cv::Vec<uchar, 10> Vec10b;
// ....
// Create the mat
cv::Mat_<Vec10b> some_mat;
// Access 4th channel
uchar value = some_mat.at<Vec10b>(i,j)(4);
// or
uchar value = some_mat.at<Vec10b>(i,j)[4];
Hope this helps you. Notice that you can omit the typedef
line, I just think it's easier this way.
OpenCV (c++) multi channel element access
Shouldn't you be using Vec3b
instead of Vec3i
?
CV_8UC3
means your image is 8 bit, 3 channels, unsigned char. While Vec3i
is for 3 channels integers and Vec3b
is for 3 channels unsigned char.
So I think you should be using Vec3b
Accessing Whole Channel in a multi channel array in opencv
Just use split and merge
Mat RGB // source mat
Mat BGR_3[3];
split(RGB,RGB_3);
BGR_3[0]//do some operation Blue channel
BGR_3[1]//do some operation Green Channel
BGR_3[2]//do some operation Red channel
//later merge
Mat dst
merge(BGR_3,3,dst);
Access multiple channels in OpenCV Mat
I think you are searching for the following:
cv::Mat M(10, 3, CV_32SC3);
cv::Mat_<cv::Vec3d> helpimg = M;
helpimg .row(0).begin()[0][0] = 2.5;
I can compile it but i didn't test it. Tell if it works. You could use it also to get the cols values:
helpimg .col(0).begin()[0][0] = 4.5;
Initialize a Multi-Channel OpenCV Mat
I was trying to use OpenCV's Vec_
and Mat_
template classes, because of this Mat_
constructor. Unfortunately, I couldn't find a working solution. All attempts lead to the same error, you already came across with. So, my guess would be, the underlying OpenCV implementation just does not support such actions, even on custom derived types.
Certainly, you have your own idea to work-around this. Nevertheless, I wanted to provide the shortest (and hopefully most efficient) solution, I could think of:
const int levels = 20;
const cv::Size size = cv::Size(123, 234);
const cv::Mat proto = cv::Mat(size, CV_16SC1, 1000);
std::vector<cv::Mat> channels;
for (int i = 0; i < levels; i++)
channels.push_back(proto);
cv::Mat A;
cv::merge(channels, A);
Mat access element OpenCV2.3
http://aishack.in/tutorials/opencvs-c-interface/
Mat a= Mat(4,3, CV_32FC1);
float elem_a= a.at(i,j); //access element aij, with i from 0 to
rows-1 and j from 0 to cols-1
Related Topics
Why Do We Actually Need Private or Protected Inheritance in C++
How Can Currying Be Done in C++
C++ Filehandling: Difference Between iOS::App and iOS::Ate
How to Iterate Over a Priority_Queue
How to Read Output from Cmd.Exe Using Createprocess() and Createpipe()
Division by Zero: Undefined Behavior or Implementation Defined in C And/Or C++
What Are Declarations and Declarators and How Are Their Types Interpreted by the Standard
Cin.Ignore(Numeric_Limits<Streamsize>::Max(), '\N')
Passing Integers as Constant References Versus Copying
What Are the Use Cases for Having a Function Return by Const Value for Non-Builtin Type
What Legitimate Reasons Exist to Overload the Unary Operator&