为什么2D图像有时被建模为指针对指针(T**)

Why are 2D images sometimes modeled as pointer to pointers (T**)?

本文关键字:指针 建模 图像 2D 为什么      更新时间:2023-10-16

一些图像数据结构实现使用指针到指针(例如T**)。第一个指针指向数据的行/列,第二个指针指向行/列中的数据元素。

与指向数据的单个指针(例如T*)相比,这种数据结构有什么优势?

我意识到这是一个宽泛的问题,所以我将这个问题缩小到C++和C编译器的现代工作("最低公分母")。

使用T**:的优点

  • 元素索引的更自然的语法(a[i][j]而不是a[i * width + j]

  • 不需要乘法进行索引(乘法在低端CPUS上仍然很昂贵,例如微控制器)

  • 可能更适合使用的任何第三方或遗留API

  • 适用于非矩形图像(即每行宽度可能不是恒定的)

  • 当您有邻域操作时,可以使边界处理更容易(在图像的开始/结束处定义附加行,这些行与它们反射的行索引混叠)

  • 允许行对齐优化效率,例如当使用SIMD时(即使图像宽度不是方便的倍数,也可以使每行SIMD对齐)

注意,如果你这样分配图像,你可以"两全其美":

T* image_buffer = malloc(height * width * sizeof(T)); // allocate "flat" image
T** image = malloc(height * sizeof(T*));              // allocate row pointers
image[0] = image_buffer;                              // init row pointers
for (int i = 1; i < height; ++i)
    image[i] = image[i - 1] + width;

通过这种方式,您可以获得一个连续的图像image_buffer,该图像可以作为image[i * width + j]访问,也可以将其视为T**图像,该图像可作为image[i][j]访问。当您有不同的API,需要不同格式的图像数据时,这会很有用。对于T**图像,它也比每行使用一个malloc的天真方法更有效。

1)您可以通过(x,y)坐标引用一个点,而不是在一维数组中计算相应的索引。(uchar**可用作uchar[x][y])

2) 您可以简单地在例如矢量运算中使用完整的行/列,方法是将行/列的相应指针(应该使用)传递到运算中。