为什么WriteableBitmap BackBufferStride与EmguCV Mat Step不同 [英] Why is WriteableBitmap BackBufferStride different from EmguCV Mat Step

查看:111
本文介绍了为什么WriteableBitmap BackBufferStride与EmguCV Mat Step不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Using netcoreapp3.1 and EmguCV 3.4.1 I create on the one hand a WriteableBitmap and on the other an EmguCV Mat. Both have same size of 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.我发现存在两个经常用于计算步幅的公式:

For the WriteableBitmap BackBufferStride = 8380 but for the Mat I get Step = 8379. I found out that there exist two different formulas often used to calculate the stride:

a)步幅=((宽度* bitsPerPixel + 31)&〜31)>> 3;

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

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

b) Stride = (width * bitsPerPixel + 7) / 8

公式 a)导致我为EmableCV Mat的值获得WriteableBitmap BackBufferStride和公式 b)的值.

Formula a) results in the value that I get for WriteableBitmap BackBufferStride and Formula b) in the value of EmguCV Mat.

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

Why are Strides different for same width and height? Which formula is the right one?

推荐答案

Stride是有关位图的行如何在内存中布局的底层实现细节.跨步与一行像素有关,要求跨步必须必须足够大,可以存储整个像素行,但可以大.正如克莱门斯指出的,任意增加步幅是完全有效的.差异导致对齐或填充字节,这些字节以前是出于速度原因添加的.

Stride is a low-level implementation detail of how the rows of a bitmap are laid out in memory. A stride relates to a row of pixels by the requirement that a stride must be big enough to store an entire row of pixels, but may be bigger. As Clemens points out it is perfectly valid to increase the stride arbitrarily; the difference results in alignment or padding bytes, historically added for speed reasons.

由于两个公式都满足该要求,所以两个都是正确的:第一个公式为像素的每一行填充内存,以使其在32位边界上对齐,而第二个公式将每一行对齐为8位.边界.但是它们两个的步幅都足够大,可以容纳整行像素.

Since both of your formulas satisfy that requirement, both are correct: the first one pads the memory for each row of pixels such that it aligns on a 32-bit boundary, while the second one aligns each row to an 8-bit boundary. But both of them result in a stride that's big enough to hold an entire row of pixels.

32位对齐的跨度可能仍在.NET land中使用,特别是与如何在内存中复制像素行有关的兼容性.

32-bit-aligned strides are probably still used in .NET land for compatibility reasons relating specifically to how rows of pixels get copied around in memory.

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

EmguCV's Mat on the other hand is something else entirely; it's a general-purpose matrix and it need not conform to whatever bitmap conventions are in use for .NET. The documentation on this page suggests that no padding bytes, or Formula B, is the default behaviour. This constructor overload lets you specify a custom step, however you do need to point it to a pre-defined buffer:

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

这篇关于为什么WriteableBitmap BackBufferStride与EmguCV Mat Step不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆