我正在使用Vips图像库处理一些大型组织学图像。与图像一起,我有一个带有坐标的数组。我想做一个二进制蒙版,它遮蔽了由坐标创建的多边形中图像的一部分。我第一次尝试使用vips绘图函数,但效率非常低,而且耗时很长(在我的实际代码中,图像大约是100000 x 100000px,多边形数组非常大)。
然后,我尝试使用PIL创建二进制掩码,效果很好。我的问题是将PIL图像转换为vips图像。它们都必须是vips图像才能使用multiply-命令。我还想从内存中写入和读取,因为我相信这比写入磁盘更快。
在im_PIL.save(memory_area,'TIFF')命令中,我必须指定和图像格式,但由于我要创建一个新图像,我不确定要在此处放置什么。
Vips.Image.new_from_memory(..)命令返回:TypeError: constructor returned NULL
from gi.overrides import Vips
from PIL import Image, ImageDraw
import io
# Load the image into a Vips-image
im_vips = Vips.Image.new_from_file('images/image.tif')
# Coordinates for my mask
polygon_array = [(368, 116), (247, 174), (329, 222), (475, 129), (368, 116)]
# Making a new PIL image of only 1's
im_PIL = Image.new('L', (im_vips.width, im_vips.height), 1)
# Draw polygon to the PIL image filling the polygon area with 0's
ImageDraw.Draw(im_PIL).polygon(polygon_array, outline=1, fill=0)
# Write the PIL image to memory ??
memory_area = io.BytesIO()
im_PIL.save(memory_area,'TIFF')
memory_area.seek(0)
# Read the PIL image from memory into a Vips-image
im_mask_from_memory = Vips.Image.new_from_memory(memory_area.getvalue(), im_vips.width, im_vips.height, im_vips.bands, im_vips.format)
# Close the memory buffer ?
memory_area.close()
# Apply the mask with the image
im_finished = im_vips.multiply(im_mask_from_memory)
# Save image
im_finished.tiffsave('mask.tif')发布于 2017-02-23 20:12:04
您将以TIFF格式从PIL中保存,但随后使用vips new_from_memory构造函数,该构造函数需要一个简单的像素值C数组。
最简单的修复方法是使用new_from_buffer,它将加载某种格式的图像,并从字符串中嗅探该格式。如下所示更改程序的中间部分:
# Write the PIL image to memory in TIFF format
memory_area = io.BytesIO()
im_PIL.save(memory_area,'TIFF')
image_str = memory_area.getvalue()
# Read the PIL image from memory into a Vips-image
im_mask_from_memory = Vips.Image.new_from_buffer(image_str, "")它应该是有效的。
在两个8位uchar图像上的vips multiply操作将生成一个16位uchar图像,该图像看起来非常暗,因为数值范围是0- 255。您可以在保存之前再次将其转换回uchar (将.cast("uchar")附加到乘法行),或者使用255代替1作为PIL掩码。
您还可以将图像作为简单的字节数组从PIL移动到VIPS。它可能会稍微快一点。
您说得对,vips中的draw操作在Python中不能很好地处理非常大的图像。用vips编写一个东西来从一组点制作任意大小的蒙版图像并不难(只需将大量的&&和<与通常的缠绕规则组合在一起),但使用PIL肯定更简单。
您还可以考虑将您的多边形蒙版作为SVG图像。libvips可以高效地加载非常大的SVG图像(它按需渲染部分),因此您只需将其放大到您的光栅图像所需的任何大小即可。
https://stackoverflow.com/questions/42373227
复制相似问题