提取Vips图像并将其保存到与PIL相同的numpy数组?

时间:2015-07-26 00:00:26

标签: python arrays numpy image-processing vips

我查看了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对象中提取正确格式的数据。

2 个答案:

答案 0 :(得分:2)

您需要.write_to_memory().new_from_memory()。 C文档在这里:

http://www.vips.ecs.soton.ac.uk/supported/8.0/doc/html/libvips/VipsImage.html#vips-image-write-to-memory

http://www.vips.ecs.soton.ac.uk/supported/8.0/doc/html/libvips/VipsImage.html#vips-image-new-from-memory

你在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()生成浮动像素。

答案 1 :(得分:1)

扩展来自user894763的答案

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 8bit彩色.jpg图片。