Reputation: 73
I have a matrix with 3 channels, and I have a problem to access and change the value of the elements. I have this code:
Mat m(4,4, CV_8UC3);
Vec3b a;
a[0] = 255;
a[1] = 0;
a[2] = 0;
m.at<Vec3b>(0,0) = a;
when I print the matrix m, I have this :
[255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
which is good, but the image that I get when I store the matrix with imwrite
is this one:
and I don't understand why it's blue and why I have a square 2x2 blue, I should have had only the first pixel red no?
Have I done a mistake somewhere?
Upvotes: 1
Views: 1120
Reputation: 50667
I don't understand why it's blue ... not red?
In OpenCV, the image format is set by the flag when you create the image e.g. CV_8UC3
means 8bit pixels, unsigned, 3 color channels. In a color image the pixel order is BGR
, data is stored in row order. Similarly, BGRA
for CV_8UC4
. So the value you set is blue instead of red, that's why you got blue.
I should have had only the first pixel ...?
The reason is that, for compressed image types e.g. JPG
, they can not guarantee to keep the content precisely. Try to imwrite()
to a un-compressed e.g. BMP
image (typically). You will get the image like:
Upvotes: 3
Reputation: 10588
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)
Upvotes: 0