Home > Enterprise >  image.Mat in EmguCV is always in BGR format?
image.Mat in EmguCV is always in BGR format?

Time:05-16

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.

CodePudding user response:

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);

enter image description here

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 as Image.

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).

  • Related