'image.Mat in EmguCV is always in BGR format?
My code is all done thinking that the input Mat
is in BGR format, so I am wondering if given an Image
object in EmguCV, the property Mat
from this object is always a BGR Mat
. Otherwise, I would need to use CvtColor
to get the BGR representation.
Example code:
byte[] data = GetPngPixelsArray(string); // Byte array in RGB format
Image<Rgb, byte> image = new Image<Rgb, byte>(width, height)
{
Bytes = data
};
CvInvoke.Imshow("image mat", image.Mat);
CvInvoke.WaitKey(0);
The function I am using to get the byte array data:
internal static byte[] GetPngPixelsArray(string filename)
{
byte[] rgbValues = null;
using (var imageIn = Image.FromFile(filename))
using (var bmp = new Bitmap(imageIn))
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
IntPtr ptr = bmpData.Scan0;
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
bmp.UnlockBits(bmpData);
}
return rgbValues;
}
In the example code above, the Imshow
function is showing the image properly, and as far as I know Imshow
always made a representation of the image using the BGR format.
So in fact the image.Mat
is in BGR format, but I've checked the EmguCV documentation and haven't found any declaration that this is as I stated.
Solution 1:[1]
Just checked the behaviour of EmguCV creating an Image
object, and the .Mat
property has the same representation as the Image
object, meaning that could be BGR or RGB.
I filled two vectors of size 750000 (500x500x3), this is what I've done:
byte[] rgbChar = new byte[750000];
byte[] bgrChar = new byte[750000];
for (int i = 0; i < rgbChar.Length; i+=3)
{
rgbChar[i] = 255;
rgbChar[i+1] = 0;
rgbChar[i+2] = 0;
bgrChar[i] = 0;
bgrChar[i+1] = 0;
bgrChar[i+2] = 255;
}
Image<Rgb, byte> imageRgb = new Image<Rgb, byte>(500, 500)
{
Bytes = rgbChar
};
Image<Bgr, byte> imageBgr = new Image<Bgr, byte>(500, 500)
{
Bytes = bgrChar
};
CvInvoke.Imshow("RGB Image", imageRgb);
CvInvoke.Imshow("RGB Image mat", imageRgb.Mat);
CvInvoke.Imshow("BGR Image", imageBgr);
CvInvoke.Imshow("BGR Image mat", imageBgr.Mat);
CvInvoke.WaitKey(0);
Edit: I would add some explanations, as it seems that the results are not self explaining.
I thought that the EmguCV Image
class, ever was creating the Mat
property as BGR. What means that?
If you check the Image
creation, you need to specify the format, eg. Image<Rgb, byte>
. I thought, that as you have to specify the format of the Image
, that the .Mat
property was a BGR representation of the RGB Image
.
Basically, I thought that the behaviour was like that:
Image<Rgb, byte>
: -> Internal conversion from RGB to BGR into the.Mat
property (Wrong).Image<Bgr, byte>
: -> No conversion, the.Mat
is BGR same asImage
.
But the real behaviour, is that the .Mat
property is just a Mat
representation of the Image
, doesn't matter if the Image
is in RGB or BGR format, the .Mat
property will be in the same representation.
This is the reason that in the two first cases the image shows blue (Imshow
ever represents the image as BGR, if the image is in RGB it will show a blue image).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | wohlstad |