如何使用加速框架(vImage)缩放灰度图像
Posted
技术标签:
【中文标题】如何使用加速框架(vImage)缩放灰度图像【英文标题】:how to scale gray scale image using accelerate framework (vImage) 【发布时间】:2012-07-24 11:23:49 【问题描述】:您好,我需要快速缩放灰度图像,所以我尝试了 vImage,但应用程序崩溃了,请帮忙。在下面的代码中 srcimg.data/dstimg.data 是指向 unsigned char 图像数据(单通道仅灰度数据)的点。
vImage_Buffer 源; src.data=srcimg.data; src.height=srcimg.cols; src.width=srcimg.rows; src.rowBytes=srcimg.cols; vImage_Buffer 目标; dest.data=dstimg.data; dest.height=dstimg.cols; dest.width=dstimg.rows; dest.rowBytes=dstimg.cols; vImageScale_Planar8(&src, &dest, NULL, kvImageNoFlags);【问题讨论】:
srcimg 和 dstimg 是来自 opencv 的 cv::Mat 对象,如果我将上面的代码替换为 cv::resize(srcimg, dstimg, dstimg.size());应用程序将按预期运行,但速度较慢。 嗨,Davids 的回答解决了这个问题,应用不再崩溃但运行速度比以前慢,请告诉我如何有效地使用 vImage。 【参考方案1】:对于 vImage/Geometry.h 中的重采样 API,我们选择使用矢量单元来提供更好的质量而不是更快的速度。这是因为向量单元通常不擅长在内存中进行分散访问,这主要是您为简单的事情所做的事情,例如线性或最近邻重采样与非单元步幅。他们似乎并不擅长使最近邻或线性过滤快速进行。因此,我们改为使用 Lanczos 过滤,它查看更大的连续像素区域以找出每个结果像素。它看起来很棒(我认为),但要获得令人敬畏的效果需要更多的工作。
另外,如果你想要的只是线性或最近邻过滤,那么 GPU 有硬件来解决这个问题!
确实,通常 vImage 中的 API 旨在为您提供比滚动自己更快的结果。
【讨论】:
【参考方案2】:cv::resize
默认使用线性插值。 vImageScale_Planar8
使用 Lanczos resampling,它更复杂,但也提供了更好的质量。你在比较苹果和橘子。
【讨论】:
【参考方案3】:首先,只是一个注释:通常高度是行,而宽度是列 - 您使用它的方式似乎很奇怪。
您是否为目标图像分配了内存:
dstimg.data = malloc(dstimg.cols * dstimg.rows);
您将部署目标设置为 ios5 或更高版本?
我在 iOS5 上使用了 Accelerate 框架,没有任何问题。
【讨论】:
感谢您解决了问题 src.height=srcimg.rows src.width=srcimg.cols;但它似乎比以前慢。我是否正确使用了 vImage,它应该提高了速度吧? 不,它不能保证在所有情况下都能提高速度。如果您多次进行此调用,您可以预先分配它需要的缓冲区(假设图像大小相同)。速度不取决于行或列值,而是处理的像素数。请注意,如果您通过二进制因子减小大小,您可能会“作弊”并抓取每个其他像素、每隔一行等,并使其更快。 如果每次都重新创建 vImage 缓冲区,您最终会得到低于最佳性能的结果,因为您不允许缓存预热。 @CameronLowellPalmer 您的评论属于问题,而不是我的回答。显然,如果您分配所需的最大内存块并重新使用它,那么第二次和以后调用的性能将会提高。那是一种 CS 101,不是吗? 首先,绝对不是 CS 101。我记得机器架构至少是大二,可能更多的是大三。 SIMD 的主题,矢量处理可能没有涵盖到他们知道如何利用它的地步。我的观点是加速,vImage 作为一个魔术盒,没有提供足够的细节来解释它是如何准确地得出加速的。在这种情况下,苹果只是挥手说,“我们愿意。”所以我的评论更多是针对 pradeepa。顺便说一句,OpenCV 会尽可能重用分配的内存。以上是关于如何使用加速框架(vImage)缩放灰度图像的主要内容,如果未能解决你的问题,请参考以下文章
使用偏移量缩放 vImage_Buffer - Cocoa Objective C
iOS 使用 vImage - 加速将 QCAR YUV 转换为 RGB
当我的 UIScrollView 缩放图像时,如何使框架正确居中?