0

我循环读取 100 张 jpeg 图像并从中提取不同的区域。

循环内容:

   VImage in = VImage::new_from_file(impath.c_str(),
          VImage::option()->
          set( "access", VIPS_ACCESS_SEQUENTIAL ) );

   VImage out = in.extract_area(x0, y0, x1 - x0, y1 - y0);
   cout << out.avg() << endl;

或者在 python 中同样的事情:

img_full = pyvips.Image.new_from_file(impath, access='sequential') 
img = img_full.extract_area(x0, y0, x1 - x0, y1 - y0)
print(img.avg()) 

我看 RSS,物理内存使用情况。它从大约 40MB 开始,然后随着每个图像的增长而增长。

这是一个图表: 在此处输入图像描述

这是具有相同作物原点、宽度/高度的 4 倍原始尺寸的图像的图表。 在此处输入图像描述

为什么会这样?是否有泄漏的地方?当我设置一个标志来跟踪泄漏时pyvips.base.leak_set(1),我得到了大约 60 MB 的报告。我还使用 cgroups 将进程的物理内存限制为 100 MB。Vips 能够运行而不会崩溃,但速度较慢。作为比较,OpenCV 中的类似操作消耗几乎恒定数量的 RSS,140 MB 或 300 MB,具体取决于图像大小。对于我的实验,vips 在 CPU 时间上赢了几次,但在内存上输了几次。

pyvips 版本:2.0.4

libvips 版本:8.6.1

4

1 回答 1

2

我试过这个测试程序:

import sys
import pyvips
import random

for filename in sys.argv[1:]:
    image = pyvips.Image.new_from_file(filename, access='sequential')
    x = random.randint(0, image.width - 2)
    y = random.randint(0, image.height - 2)
    w = random.randint(1, image.width - x)
    h = random.randint(1, image.height - y)
    print 'filename =', filename, 'avg =', image.crop(x, y, w, h).avg()

我是这样运行的:

$ mkdir samples
$ for i in {1..2000}; do cp ~/pics/k2.jpg samples/$i.jpg; done
$ python soak.py samples/*

k2.jpg是 2k x 1.5k RGB jpg 图像。当它运行时,我在 RES 中观看了它top。它在开始时略有上升,但在大约 100 个图像之后稳定在 75MB 左右,并在剩余的 1900 次迭代中保持不变。这是 py27、pyvips 2.0.4、libvips 8.6.1。

libvips 保留最近操作的缓存。通常这是无害的(并且有帮助),但在某些情况下它可能会触发不必要的内存使用。

您可以尝试添加:

pyvips.cache_set_max(0)

在您的程序开始附近。在这个例子中,它把 memuse 的峰值从 75mb 降到了 38mb。

于 2018-01-30T16:18:26.580 回答