提取 Vips 图像并将其保存到与 PIL 相同的 numpy 数组?
Extract Vips image and save it to numpy array same as with PIL?
我查看了 Vips 的一些可用文档 Here,但尚未找到答案。
我想将图像放入一个 numpy 3D 数组,类似于 PIL 图像以这种方式自动处理的方式:
In[1]: import numpy
In[2]: from PIL import Image
In[3]: image = Image.open('43.jpg')
In[4]: image
Out[4]: <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=3216x2136 at 0x7F0C8D8B9950>
In[5]: imgArray2 = numpy.asarray(image, dtype=numpy.float32)
In[6]: imgArray2.shape
Out[6]: (2136, 3216, 3)
.
这是我目前为 Vips 准备的...
In[1]: import numpy
In[2]: from gi.repository import Vips
In[3]: image = Vips.Image.new_from_file('43.jpg')
In[4]: image
Out[4]: <Image object at 0x7f0c9a66c5f0 (VipsImage at 0x338a190)>
In[5]: imgArray2 = numpy.asarray(image, dtype=numpy.float32)
Out[5]: ValueError: setting an array element with a sequence.
最后我得到了那个错误,因为我没有从 Vips Image 对象中以正确的格式提取数据。
您需要 .write_to_memory()
和 .new_from_memory()
。 C 文档在这里:
您可以像这样在 Python 中使用它们:
$ python
Python 2.7.9 (default, Apr 2 2015, 15:33:21)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from gi.repository import Vips
>>> x = Vips.Image.new_from_file("/home/john/pics/k2.jpg")
>>> y = x.write_to_memory()
>>> type(y)
<type 'str'>
>>> z = Vips.Image.new_from_memory(y, x.width, x.height, x.bands, Vips.BandFormat.UCHAR)
>>> x.avg()
102.79218031609196
>>> z.avg()
102.79218031609196
这就是将 JPEG 文件发送到一个字符串,然后再次从该字符串创建一个新图像。该字符串只是构成图像值的字节序列,因此对于像这样的 8 位 RGB 图像,它将以:
开头
R1 G1 B1
其中 R1 是图像中左右像素的红色通道值。像素存储为一系列扫描线,从上到下。
numpy 需要浮动像素吗?你可以让vips用x.cast(Vips.BandFormat.FLOAT).write_to_memory()
生成float pixels。
扩展用户 894763 的回答
from gi.repository import Vips
from PIL import Image
import numpy as np
with open(path_or_url) as image_file:
start_pillow = time.time()
pillow_img = np.asarray(Image.open(image_file))
print('Pillow Time:', time.time()-start_pillow)
print('original shape', pillow_img.shape)
start_vips = time.time()
img = Vips.Image.new_from_file(path_or_url)
print('Image bit depth', img.Bbits)
mem_img = img.write_to_memory()
# Note that my specific image was 8 bit
np_3d = np.fromstring(mem_img, dtype=np.uint8).reshape(img.width, img.height, 3)
print('Vips Time:', time.time()-start_vips)
print('final shape', np_3d.shape)
# Just to verify we have the same result
print('Sum of the Differences:', np.sum(np_3d-pillow_img))
输出:
('Pillow Time:', 0.3100590705871582)
('original shape', (2500, 2500, 3))
('Image bit depth', 8)
('Vips Time:', 0.1401970386505127)
('final shape', (2500, 2500, 3))
('Sum of the Differences:', 0)
这是一张 2500x2500 8 位彩色 .jpg 图片。
我查看了 Vips 的一些可用文档 Here,但尚未找到答案。
我想将图像放入一个 numpy 3D 数组,类似于 PIL 图像以这种方式自动处理的方式:
In[1]: import numpy
In[2]: from PIL import Image
In[3]: image = Image.open('43.jpg')
In[4]: image
Out[4]: <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=3216x2136 at 0x7F0C8D8B9950>
In[5]: imgArray2 = numpy.asarray(image, dtype=numpy.float32)
In[6]: imgArray2.shape
Out[6]: (2136, 3216, 3)
.
这是我目前为 Vips 准备的...
In[1]: import numpy
In[2]: from gi.repository import Vips
In[3]: image = Vips.Image.new_from_file('43.jpg')
In[4]: image
Out[4]: <Image object at 0x7f0c9a66c5f0 (VipsImage at 0x338a190)>
In[5]: imgArray2 = numpy.asarray(image, dtype=numpy.float32)
Out[5]: ValueError: setting an array element with a sequence.
最后我得到了那个错误,因为我没有从 Vips Image 对象中以正确的格式提取数据。
您需要 .write_to_memory()
和 .new_from_memory()
。 C 文档在这里:
您可以像这样在 Python 中使用它们:
$ python
Python 2.7.9 (default, Apr 2 2015, 15:33:21)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from gi.repository import Vips
>>> x = Vips.Image.new_from_file("/home/john/pics/k2.jpg")
>>> y = x.write_to_memory()
>>> type(y)
<type 'str'>
>>> z = Vips.Image.new_from_memory(y, x.width, x.height, x.bands, Vips.BandFormat.UCHAR)
>>> x.avg()
102.79218031609196
>>> z.avg()
102.79218031609196
这就是将 JPEG 文件发送到一个字符串,然后再次从该字符串创建一个新图像。该字符串只是构成图像值的字节序列,因此对于像这样的 8 位 RGB 图像,它将以:
开头R1 G1 B1
其中 R1 是图像中左右像素的红色通道值。像素存储为一系列扫描线,从上到下。
numpy 需要浮动像素吗?你可以让vips用x.cast(Vips.BandFormat.FLOAT).write_to_memory()
生成float pixels。
扩展用户 894763 的回答
from gi.repository import Vips
from PIL import Image
import numpy as np
with open(path_or_url) as image_file:
start_pillow = time.time()
pillow_img = np.asarray(Image.open(image_file))
print('Pillow Time:', time.time()-start_pillow)
print('original shape', pillow_img.shape)
start_vips = time.time()
img = Vips.Image.new_from_file(path_or_url)
print('Image bit depth', img.Bbits)
mem_img = img.write_to_memory()
# Note that my specific image was 8 bit
np_3d = np.fromstring(mem_img, dtype=np.uint8).reshape(img.width, img.height, 3)
print('Vips Time:', time.time()-start_vips)
print('final shape', np_3d.shape)
# Just to verify we have the same result
print('Sum of the Differences:', np.sum(np_3d-pillow_img))
输出:
('Pillow Time:', 0.3100590705871582)
('original shape', (2500, 2500, 3))
('Image bit depth', 8)
('Vips Time:', 0.1401970386505127)
('final shape', (2500, 2500, 3))
('Sum of the Differences:', 0)
这是一张 2500x2500 8 位彩色 .jpg 图片。