Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从平铺图像中进行双线性采样有什么好的策略吗?_C++_C_Image_Optimization - Fatal编程技术网

C++ 从平铺图像中进行双线性采样有什么好的策略吗?

C++ 从平铺图像中进行双线性采样有什么好的策略吗?,c++,c,image,optimization,C++,C,Image,Optimization,对图像进行双线性采样时,需要4个相邻像素。这对于内存中线性的图像来说很容易。 但是,如果图像是由内存中的单个磁贴组成的,则在最坏的情况下,四个样本中的每一个都位于不同的磁贴中。 有哪些策略可以加快这一速度?假设瓷砖是两个正方形的幂。在大多数情况下,聚集应位于一个平铺内 有一个瓦片指针的w x h数组T,每个瓦片是一个k x k像素的原始数组。如何制作一个快速聚集(x,y,dest)函数,返回(x,y)、(x+1,y)、(x,y+1)、(x+1,y+1)处的四个像素 如果平铺不是原始指针,而是可能

对图像进行双线性采样时,需要4个相邻像素。这对于内存中线性的图像来说很容易。 但是,如果图像是由内存中的单个磁贴组成的,则在最坏的情况下,四个样本中的每一个都位于不同的磁贴中。 有哪些策略可以加快这一速度?假设瓷砖是两个正方形的幂。在大多数情况下,聚集应位于一个平铺内

有一个瓦片指针的w x h数组T,每个瓦片是一个k x k像素的原始数组。如何制作一个快速聚集(x,y,dest)函数,返回(x,y)、(x+1,y)、(x,y+1)、(x+1,y+1)处的四个像素

如果平铺不是原始指针,而是可能需要分页的对象,该怎么办?因此,如果(T[o]==0)PageIn(o),则需要进行测试

另外,整个图像的边缘应该夹紧,所以值(-1,y)=值(0,y)等


这是一个非常开放的问题。我知道怎么做。我正在寻找技巧和技巧,如何快速做到这一点

您始终可以将指针预先分配给平铺中的行。将它们排序为一个大的指针数组,您可以通过访问指针数组访问平铺扫描线

char* ptr [numTilesH][numTilesV * tileHeight];

// ... fill the pointer array with pointers to the beginning of each 
// scanline in a tile...

// ...assume 256 grey scales
unsigned char getPixel (int x, int y) {
   int hTileNr = x / tileWidth;
   int hTileOffs = x % tileWidth;

   char * pixelPtr = ptr [hTileNr][y];
   return pixelPtr [hTileOfs];
}

在这种情况下,优化是典型的内存与CPU折衷。正如您在这里看到的,对像素的访问是一个带余数的除法,以及两个数组访问。一旦设置了指针数组,速度应该非常快。但是,平铺越多,扫描线指针所需的内存就越大——可能达到了指针阵列过于昂贵的程度。

您始终可以将指针预先分配给平铺内的线。将它们排序为一个大的指针数组,您可以通过访问指针数组访问平铺扫描线

char* ptr [numTilesH][numTilesV * tileHeight];

// ... fill the pointer array with pointers to the beginning of each 
// scanline in a tile...

// ...assume 256 grey scales
unsigned char getPixel (int x, int y) {
   int hTileNr = x / tileWidth;
   int hTileOffs = x % tileWidth;

   char * pixelPtr = ptr [hTileNr][y];
   return pixelPtr [hTileOfs];
}

在这种情况下,优化是典型的内存与CPU折衷。正如您在这里看到的,对像素的访问是一个带余数的除法,以及两个数组访问。一旦设置了指针数组,速度应该非常快。但是,平铺越多,扫描线指针所需的内存就越大—可能达到指针阵列过于昂贵的程度。

让平铺存储冗余像素—也就是说,在两个相邻平铺的平铺边界附近存储像素(如果像素靠近平铺角,则实际存储在4个平铺中)

这完全消除了以浪费内存为代价读取像素(包括边界附近)的开销。此外,写入像素更难-写入单个像素可能需要更新多达4个分片。但是,如果计算整个图像,生成冗余像素是一个统一的过程

您可能需要为磁贴选择特定的大小。例如,宽度=62像素(当像素=字节时);添加两个冗余像素后,宽度等于缓存线(假设为64字节)


如果使用双三次插值,则从每一侧添加2个冗余像素。

让您的磁贴存储冗余像素-即,在相邻的两个磁贴中靠近磁贴边界存储像素(如果像素靠近磁贴的角,则实际上在4个磁贴中存储像素)

这完全消除了以浪费内存为代价读取像素(包括边界附近)的开销。此外,写入像素更难-写入单个像素可能需要更新多达4个分片。但是,如果计算整个图像,生成冗余像素是一个统一的过程

您可能需要为磁贴选择特定的大小。例如,宽度=62像素(当像素=字节时);添加两个冗余像素后,宽度等于缓存线(假设为64字节)


如果使用双三次插值,则从每一侧添加2个冗余像素。

能否将瓷砖宽度增加到2像素或更高?假设您有16x16个平铺,将它们制作为18x18个平铺,其中新行和列来自附近的平铺。您仍然认为它们是16x16瓦片,但是当涉及插值边框像素时,您的邻域数据只是加载在附加行/列中。@玛格丽特布卢姆,我将您的评论转换为答案。事实上,我在过去使用过这个想法(对于1位像素),所以在我写我的答案之前,我甚至没有读过你的评论。你能让瓷砖宽2像素,高2像素吗?假设您有16x16个平铺,将它们制作为18x18个平铺,其中新行和列来自附近的平铺。您仍然认为它们是16x16瓦片,但是当涉及插值边框像素时,您的邻域数据只是加载在附加行/列中。@玛格丽特布卢姆,我将您的评论转换为答案。事实上,我在过去使用过这个想法(对于1位像素),所以在我写我的答案之前,我甚至没有读过你的评论。实际上我已经尝试过了。但是,像高斯滤波器而不是双线性滤波器这样的大面积滤波器呢?最终你只是在转移问题。我同意你的解决方案对书面问题来说是一个很好的解决方案,但并不符合它的精神。复制边界的另一个大问题是类似mip映射的技术。两块瓷砖的力量在2x2的盒子里很好地取样。事实上,你的答案非常有帮助。如果我真的只需要取一个双线性样本,这绝对是正确的方法。我确实用它做过实验。但是,像高斯滤波器而不是双线性滤波器这样的大面积滤波器呢?最终你只是在转移问题。我同意你的解决方案对书面问题来说是一个很好的解决方案,但并不符合它的精神。复制边界的另一个大问题是类似mip映射的技术。两块瓷砖的力量在2x2的盒子里很好地取样。事实上,你的答案非常有帮助。如果我真的只需要采取双线性样本,这绝对是正确的方法。