繁体   English   中英

为什么 WriteableBitmap BackBufferStride 与 EmguCV Mat Step 不同

[英]Why is WriteableBitmap BackBufferStride different from EmguCV Mat Step

使用 netcoreapp3.1 和 EmguCV 3.4.1,我一方面创建了 WriteableBitmap,另一方面创建了 EmguCV Mat。 两者的尺寸相同,均为 2793 x 2585

var wb = new WriteableBitmap(2793, 2585, 96, 96, PixelFormats.Bgr24, null);
int wbStride = wb.BackBufferStride; //8380 

var m = new Mat(2585, 2793, DepthType.Cv8U, 3);
int matStride = m.Step; //8379

对于 WriteableBitmap BackBufferStride = 8380 但对于 Mat 我得到 Step = 8379。我发现通常用于计算步幅的两个不同公式:

a)步幅 = ((width * bitsPerPixel + 31) & ~31) >> 3;

b)步幅 = (width * bitsPerPixel + 7) / 8

公式a)导致我为 WriteableBitmap BackBufferStride 和公式b)在 EmguCV Mat 的值中获得的值。

为什么相同宽度和高度的步幅不同? 哪个公式是正确的?

不确定为什么BackBufferStride会返回该值。

但是,任何大于或等于最小步幅(width * bpp + 7) / 8的值都对 bitmap 的步幅有效。 只需要步幅足够大,即每条扫描线有足够的字节来保存所有位。

您可以尝试以下代码并添加任何您喜欢的步幅,例如stride += 100; . 只需确保步幅也用于计算像素缓冲区的大小。

var width = 2793;
var height = 2585;
var stride = (width * PixelFormats.Bgr24.BitsPerPixel + 7) / 8; // 8379

stride += 100;

var buffer = new byte[stride * height];

for (int y = 0; y < height; y++)
{
    for (int x = y % 10; x < width; x += 10)
    {
        buffer[stride * y + 3 * x + 0] = 0xFF;
        buffer[stride * y + 3 * x + 1] = 0xFF;
        buffer[stride * y + 3 * x + 2] = 0xFF;
    }
}

var bitmap = BitmapSource.Create(
    width, height, 96, 96, PixelFormats.Bgr24, null, buffer, stride);

Stride 是 bitmap 的行如何在 memory 中布局的低级实现细节。 步幅与一行像素相关,要求步幅必须足够大以存储整行像素,但可能更大。 正如 Clemens 所指出的,随意增加步幅是完全有效的。 差异导致 alignment 或填充字节,历史上出于速度原因添加。

由于您的两个公式都满足该要求,因此两者都是正确的:第一个公式为每行像素填充 memory,使其在 32 位边界上对齐,而第二个公式将每一行与 8 位边界对齐。 但是它们都导致了一个足够大的步幅来容纳一整行像素。

出于兼容性原因,.NET 领域可能仍在使用 32 位对齐的步幅,具体与如何在 memory 中复制像素行有关。

另一方面,EmguCV 的Mat完全是另外一回事。 它是一个通用矩阵,它不需要符合用于 .NET 的任何 bitmap 约定。 此页面上的文档表明默认行为是没有填充字节或公式 B。 此构造函数重载允许您指定自定义步骤,但是您确实需要将其指向预定义的缓冲区:

var buffer = Marshal.AllocHGlobal(2585 * 8380);
var m = new Mat(2585, 2793, DepthType.Cv8U, 3, buffer, 8380);
int matStride = m.Step; //8380
Marshal.FreeHGlobal(buffer);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM