我正在处理30,000 x 30,000像素的TIFF图像,并希望一次平均11张图像。
如果可能的话,我更愿意在python中使用它,并且想知道最好的方法是什么?
我应该使用OpenCV
还是仅使用numpy
完成?
平均每个RGBA通道是否会独立提高性能?
或者我应该将图像分成较小的图像并单独处理它们,然后将生成的碎片拼接在一起?
直接使用openCV这样会导致内存错误:
im0 = cv2.imread( '5014.tif' )
im1 = cv2.imread( '5114.tif' )
im2 = cv2.imread( '5214.tif' )
im3 = cv2.imread( '5314.tif' )
im4 = cv2.imread( '5414.tif' )
cv2.imwrite( 'avg.tif', .01*im0 -.002*im1 -.002*im2 -.002*im3 -.002*im4 )
答案 0 :(得分:3)
libvips是用于大图像的图像处理系统。它可以流式传输图像,而不是单独执行加载/处理/保存步骤,因此您可以使用比计算机内存量大得多的图像。它有一个方便的high-level python binding。这类任务应该是quicker than opencv。
你可以用Python解决你的问题:
#!/usr/bin/python
import sys
from gi.repository import Vips
if len(sys.argv) < 3:
print("usage: %s output-file in1 in2 ..." % sys.argv[0])
sys.exit(1)
input_names = sys.argv[2:]
n_images = len(input_names)
outfile = sys.argv[1]
sum = 0
for filename in input_names:
new_image = Vips.Image.new_from_file(filename, access =
Vips.Access.SEQUENTIAL_UNBUFFERED)
sum += new_image
avg = sum / n_images
# avg will be a float image, cast back to 8-bit for write, or we'll
# get a float tiff
avg.cast(Vips.BandFormat.UCHAR).write_to_file(outfile)
像这样跑:
$ time ./avg.py x.tif ~/pics/wtc*.tif
memory: high-water mark 38.50 MB
real 0m5.759s
user 0m2.584s
sys 0m0.457s
在具有机械硬盘的机器上平均有四万个10,000 x 10,000 RGB图像,所以我猜你的数据集大约需要两分钟。内存使用量应在100mb左右。
答案 1 :(得分:2)
aListOfFNAMEs = [ ''5014.tif', ... ] # SETUP: FNAMEs
aListOfCOEFFs = [ .01, -.002, -.002, -.002, -.002, .... ] # COEFFs till the 11-th
anInputIMG = cv2.imread( aListOfFNAMEs[0] ) # LOAD
anAveragedIMG = numpy.zeros( anInputIMG.shape ) # ensure .copy, not view
anAveragedIMG += aListOfCOEFFs[0]*anInputIMG # process the 1st LOAD-ed
for aPtr in range( 1, len(aListOfCOEFFs ) ): # iterate, process the rest
anInputIMG = cv2.imread( aListOfFNAMEs[aPtr] ) # re-use MEM on LOAD(s)
anAveragedIMG += aListOfCOEFFs[aPtr] * anInputIMG # process <next>
cv2.imwrite( "avg.TIF", anAveragedIMG ) # SAVE
del anInputIMG # release for GC
del anAveragedIMG # release for GC, DONE.
更快矢量化矩阵运算 - 由于处理允许numpy / openCV矢量化矩阵运算,RGB-colorplane分离为独立处理不强>提高速度,恰恰相反。 (以上代码以这种方式运行)
最快基于GPU的阻止操作 - 尽管可能,会介绍您的项目,以便花费大量时间安排GPU设备/ HOST设备数据传输,以便每个块移动的数据少于GPU-DRAM所允许的大小。请求的计算具有如此低的数学/计算密度,这使得这些开销无法进入基于GPU的模式。
答案 2 :(得分:0)
您的“堆叠”具有“形状”(30000, 30000, 4, 11)
。我不担心以任何方式手动循环这两个维度 - 我会担心你遇到的内存不足。
我不知道OpenCV语法,但是如果您可以在没有内存问题的情况下读取一个图像,请执行以下操作:
image_filenames = ['5014.tif', '5114.tif', ...]
N = float(len(image_filenames))
output = # empty array of image dimensions
for image_filename in image_filenames:
# read in this image
# add image / N to output
# save the output