image.Mat 在 EmguCV 中总是采用 BGR 格式?

image.Mat in EmguCV is always in BGR format?

我的代码都认为输入 Mat 是 BGR 格式,所以我想知道如果在 EmguCV 中给定一个 Image 对象,属性 Mat 来自此对象的始终是 BGR Mat。否则,我需要使用 CvtColor 来获取 BGR 表示。

示例代码:

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

我用来获取字节数组数据的函数:

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

在上面的示例代码中,Imshow 函数正确显示了图像,据我所知,Imshow 总是使用 BGR 格式表示图像。

所以实际上 image.Mat 是 BGR 格式,但我已经检查了 EmguCV 文档,但没有找到任何声明表明这是我所说的。

刚刚检查了 EmguCV 创建 Image 对象的行为,.Mat 属性 与 Image 对象具有相同的表示,这意味着可能是 BGR或 RGB。

我填充了两个大小为 750000 (500x500x3) 的向量,这就是我所做的:

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

编辑:我会添加一些解释,因为结果似乎无法自我解释。

我认为 EmguCV Image class、ever 正在创建 Mat 属性 作为 BGR。那是什么意思?

如果勾选Image创建,需要指定格式,例如。 Image<Rgb, byte>。我认为,由于您必须指定 Image 的格式,因此 .Mat 属性 是 RGB Image.

的 BGR 表示

基本上,我认为行为是这样的:

  • Image<Rgb, byte> : -> 从 RGB 到 BGR 的内部转换成 .Mat 属性(错误)。
  • Image<Bgr, byte> : -> 无转换,.MatImage.
  • 的 BGR 相同

但真正的行为是 .Mat 属性 只是 ImageMat 表示,如果 Image 为 RGB 或 BGR 格式,.Mat 属性 将采用相同的表示形式。

这就是前两种情况下图像显示为蓝色的原因(Imshow 曾经将图像表示为 BGR,如果图像为 RGB,则会显示蓝色图像)。