我使用reticulate
包中的一些Python功能创建了一个函数,具体来说是使用PIL
打开图像:
image <- "~/Desktop/image.jpg"
pil.image <- reticulate::import( "PIL.Image", convert = FALSE )
img <- pil.image$open( image )
我随后对图像进行了一些处理(我正在提取多个裁剪图像),这很正常。下面是我正在做的示例(outputs
是我需要的裁剪图像的数据框,因此 crop.grid
只是一个包含4个数字的向量。
crop.grid <- c( outputs$x.start[x],
outputs$y.start[x],
outputs$x.stop[x],
outputs$y.stop[x] )
crop.grid <- as.integer( crop.grid )
crop.grid <- reticulate::r_to_py( crop.grid )
output.array <- img$crop( box = crop.grid )
output.array$save( output.filename )
接下来,我希望将图像从内存中清除(我打开的图像非常大,所以需要大量内存)。我尝试在Python中关闭图像:
img$close()
同样也适用于R语言:
rm( img )
gc()
我将对象替换为我知道非常小的东西。
img <- reticulate::r_to_py( 1L )
所有这些东西都可以正常运行,但我的 RAM 仍然显示为非常满。我尝试将它们与我创建的每个 python 对象一起使用,但唯一有效地清除 RAM 的方法是重新启动 R 会话。
我知道在 python
中最好使用 with
打开图像,以便在进程结束时清除它,但我不确定如何使用reticulate
来实现它。
--- 使用类比的 python
版本更新:
如果我直接在 python 中执行以上操作:
from PIL import Image
img = Image.open( "/home/user/Desktop/image.jpg" )
output = img.crop( [0,0,100,100] )
然后关闭事物:
output.close()
img.close()
内存被清除。然而从R内部执行同样的操作却不起作用。例如:
output.array$close()
img$close()
gc() # for good measure
无法清除内存。
with(pil.image$open( image ) %as% img, { img$crop(r_to_py( c(0,0,100,100)))$save("myfile.jpg") })
。 - lukeAoutput.array<-img$crop(box=crop.grid)
这一步骤会导致内存占用增加,但我在函数中重复运行该步骤,每次迭代似乎都不会重新读取图像(只有第一次迭代需要较长时间)。关闭output.array
、rm
和gc
似乎仍然无法清除RAM。 - rosscovawith(pil.image$open( image ) %as% img, { with(img$crop(r_to_py( c(0,0,100,100))) %as% output.array, { output.array$save("myfile.jpg") }) })
- 只是试错。 - lukeAR
中操作with
,因此只有R
对象被删除。Python对象(我假设它坐落在后台环境中)仍然存在。 - rosscovaR
中使用gc()
,但没有效果。不幸的是,由于(我认为)reticulate
启动了一个外部的python
会话,该会话可能是内存分配问题所在的地方,因此在R
会话中运行gc()
没有任何区别。重新启动R
明确地关闭了python
会话,因此一个reticulate
函数可以在不重新启动R
的情况下完成这个操作,但是一个能够正确清除对象而不关闭该会话的函数将更好。 - rosscova