2012-08-16 26 views
1

我正在使用Cocoa Touch中的vImages,在我的情况下,它基本上是ARGB-float-Arrays,我需要做二次采样。低通滤波对于使用vImage函数并不是问题,但是如何选择一个2x2像素(假设我想通过因子2进行二次采样)?当然,我可以使用vDSP步进功能,但这只适用于水平二次采样,而不适用于垂直二次采样。iOS可可触摸vImage子采样

我希望以下内容能阐明我打算做的事情。我想选择标有X的所有像素,如图此图像中:

X O X O X O 
O O O O O O 
X O X O X O 
O O O O O O 
X O X O X O 
O O O O O O 

但由于存储是线性的,我的数组是这样的:

X O X O X O O O O O O O X O X O X O O O O O O O X O X O X O O O O O O O 

我怎样才能在执行二次抽样合理的时尚?

编辑:我正在寻找一种有效的方式来做一个给定的位图存储为一维浮点数组(包括负值)的二维下采样。

回答

1

现实情况是,当你正在进行这种二次采样时,没有什么聪明的事情可以做;跨进程内存访问不会承认很多技巧要快,所以你使用的任何库代码将基本上等同于你可能在几分钟内编写的C代码。我会用一个简单的C实现。

我相信这可以在GPU上合理高效地完成,但除非您的数据已经处于GPU环境中,否则这不会成为性能优势。如果您必须首先在那里传输数据,那么这种成本将会大大减少实际操作中的任何性能节省。

0

我一直这样做 - 你需要知道图像的宽度。所以你有一个指针,你将其他像素换成一行,然后你将指针碰到一整行,然后开始把所有其他像素都取到行的末尾,然后再将指针碰到整行。对我来说,我通常把图像渲染成位图上下文,所以我知道每个像素的字节数,pixesl的宽度和每行的字节数(但是对于你来说,它可能会只是宽度x每像素)。

编辑:对不起,我不清楚。给定一个x列和y行的位图,创建一个新的CGBitMapContext,并通过使用上面的示例获取“其他”像素并将其写入此新的上下文。现在你有第二个位图,如果你说你想在你的问题中的像素。利用该位图,您现在可以应用所需的任何进一步处理。

+0

我已经尝试过使用Core Graphics来实现这个功能,它的功能很强大。问题是,它是线性逼近,与我打算做的“真实”低通滤波相反。此外,我需要使用负值,它不能显示为uint8_t。我希望使用一些vDSP函数来获得更好的性能,而不是实现复制循环。据我所见,这可能不适用于垂直下采样,但也许我还没有看到它。 – Chris 2012-08-17 09:15:34

+0

我编辑了我的回复,甚至认为上面的评论似乎没有包含在你原来的问题中。你可能想进一步扩展你的问题。我所提议的根本不是进行任何滤镜处理,也不是使用Core Graphics来处理像素和制作图像(这将是您创建的像素的精确渲染)。 – 2012-08-17 10:41:09

+0

我很抱歉我的问题不清楚。谢谢您的回答。我将用以下编辑我的问题:我正在寻找一种有效的方法来对存储为一维浮点数组(包含负值)的给定位图执行二维下采样。 – Chris 2012-08-17 11:34:16

0

由于存储器是线性的,可以让解释源矩阵作为双宽度和一半高度的矩阵:

X O X O X O O O O O O O 
X O X O X O O O O O O O 
X O X O X O O O O O O O 

与交织复制(跨距= 2)后,我们有:

X X X O O O 
X X X O O O 
X X X O O O 

然后使用vDSP_mmov将左侧子矩阵复制到结果子矩阵。

对于交错复制(第一阶段)可以使用vDSP_zvmov函数,但是它并没有针对浮点数进行优化。可能vDSP_vsadd0作为标量参数将工作得更快。

0

我意识到这主要只是一个“如何使用指针”的问题。但是,您计划执行的操作不会产生高质量图像。它看起来像素化,一些细节会放大,其他细节会丢失。

幸运的是,图像重采样技术是一个很好的研究区域,这里有很多的选择。

如果你是在GPU上,你所描述的操作仅仅是OpenCL中或OpenGL最近的抽样方法,因此,如果你在那里,你可以计算出你想要的坐标,并挑选最接近。线性采样方法可能会更好看。

如果您在CPU上,那么你有一些选择。如果数据保存在CGImageRef中,则可以使用缩放将其呈现为CGBitmapContextRef,以便在每个维度中将图像的大小减小两倍。我相信这会给你线性重采样,但是这个细节应该在某处可用。

如果数据是坐在C数组,然后vImageScale_ARGBFFFF()是你的朋友。只需创建一个1/2高度和1/2宽度的新缓冲区,并使用该功能将其缩减到正确的值。这将使用Lanczos重采样,虽然速度稍慢但看起来更好。 (这可能更适合浮点数据,我认为您选择这是因为您需要高保真度。)Lanczos内核具有将低通滤波和降采样合并为一个通道的优点,因此可以做的更少。