为什么cv::resize如此缓慢?

15

我正在对实时视频流进行一些边缘检测:

- (void)processImage:(Mat&)image;
{
        cv::resize(image, smallImage, cv::Size(288,352), 0, 0, CV_INTER_CUBIC);
        edgeDetection(smallImage);
        cv::resize(smallImage, image, image.size(), 0, 0, CV_INTER_LINEAR);
}

edgeDetection 进行了相当重的工作,在视频帧大小为1280x720时帧率非常低。添加 resize 调用显著地降低了帧率,这与我的期望完全相反。这是因为缩放操作很慢,还是我做错了什么?

smallImage 在头文件中声明如下:

@interface CameraController : UIViewController
<CvVideoCameraDelegate>
{
    Mat smallImage;
}

它没有初始化,但运行得很好。

3个回答

23

调整图像大小很慢,而且您每次处理帧时都要进行两次调整大小。有几种方法可以在某种程度上改善您的解决方案,但您必须提供有关您正在尝试解决的问题的更多详细信息。

首先,在检测边缘之前调整图像大小会导致向边缘检测提供更少的信息,因此会检测到更少的边缘 - 或者至少会使边缘检测变得更加困难。

此外,所使用的调整大小算法会影响其速度,如果我没有记错,CV_INTER_LINEAR是cv::resize的最快算法 - 而您正在为第一次调整大小使用CV_INTER_CUBIC。

调整图像大小的另一种选择是代替调整大小,对原始图像的较小区域进行处理。您应该查看OpenCV中的图像感兴趣区域(ROI)。这是非常容易做到的,您可以在该网站上找到许多有关该主题的问题。缺点是您只能检测一个区域内的边缘,而不是整个图像,这可能是可以接受的,具体取决于问题。

如果您真的想要调整图像大小,那么OpenCV开发人员通常会在处理较小图像时使用pyrDownpyrUp函数,而不是resize。我认为这是因为它更快,但您可以测试一下以确保。 在此链接中了解有关pyrDown和pyrUp的更多信息。

关于cv :: resize算法,以下是列表:

INTER_NEAREST - a nearest-neighbor interpolation
INTER_LINEAR - a bilinear interpolation (used by default)
INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood

不能确定INTER_LINEAR是否是最快的,但肯定比INTER_CUBIC快。


6
实际上,对我来说,INTER_NEAREST 是最快的。 - étale-cohomology

12

INTER_NEAREST是最快且质量最差的方法。在缩小图像时,对于每个像素,它只使用最接近理论位置的像素。

INTER_LINEAR是性能和质量的良好平衡,但比INTER_NEAREST更慢。

INTER_CUBIC比INTER_LINEAR更慢,因为它使用了更多的插值。

INTER_LANCZOS4是质量最好的算法,但比其他算法更慢。

您可以在这里找到一篇好的比较文章:http://tanbakuchi.com/posts/comparison-of-openv-interpolation-algorithms/


链接已失效。 - Stepan Yakovenko
新链接: “OpenCV插值方法比较(Anthony Tanbakuchi)(因其网站崩溃而备份)” https://gist.github.com/georgeblck/e3e0274d725c858ba98b1c36c14e2835 - Johan

2

在4核CPU上进行时间试验(不使用GPU)。

从:(1440,2560,3) 到:(300,300,3)

从快到慢排列:

INTER_NEAREST resize:  Time Taken: 0:00:00.001024
INTER_LINEAR resize:   Time Taken: 0:00:00.004321
INTER_CUBIC resize:    Time Taken: 0:00:00.007929
INTER_LANCZOS4 resize: Time Taken: 0:00:00.021042
INTER_AREA resize:     Time Taken: 0:00:00.065569

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接