Tôi có một ma trận theo kiểu mảng Numpy. Làm thế nào tôi có thể viết nó vào đĩa như một hình ảnh? Mọi định dạng đều hoạt động (png, jpeg, bmp ...). Một hạn chế quan trọng là PIL không có mặt.
Tôi có một ma trận theo kiểu mảng Numpy. Làm thế nào tôi có thể viết nó vào đĩa như một hình ảnh? Mọi định dạng đều hoạt động (png, jpeg, bmp ...). Một hạn chế quan trọng là PIL không có mặt.
Câu trả lời:
Bạn có thể sử dụng PyPNG . Đó là một bộ mã hóa / giải mã PNG mã nguồn mở thuần túy (không phụ thuộc) và nó hỗ trợ viết các mảng NumPy dưới dạng hình ảnh.
Cái này sử dụng PIL, nhưng có lẽ một số có thể thấy nó hữu ích:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
EDIT : scipy
Phiên bản hiện tại bắt đầu bình thường hóa tất cả các hình ảnh để min (dữ liệu) trở thành màu đen và max (dữ liệu) trở thành màu trắng. Điều này là không mong muốn nếu dữ liệu phải là mức xám chính xác hoặc các kênh RGB chính xác. Giải pháp:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Một câu trả lời bằng PIL (chỉ trong trường hợp nó hữu ích).
đưa ra một mảng numpy "A":
from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")
bạn có thể thay thế "jpeg" bằng hầu hết mọi định dạng bạn muốn. Chi tiết hơn về các định dạng ở đây
from PIL import Image
để làm cho nó rõ ràng ...
Với matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
Hoạt động với matplotlib 1.3.1, tôi không biết về phiên bản thấp hơn. Từ chuỗi tài liệu:
Arguments:
*fname*:
A string containing a path to a filename, or a Python file-like object.
If *format* is *None* and *fname* is a string, the output
format is deduced from the extension of the filename.
*arr*:
An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
matplotlib.pyplot.imsave
trong matplotlib 2+
import matplotlib.pyplot as plt
và sau đóplt.imsave('name.png', array)
Python thuần túy (2 & 3), một đoạn không có sự phụ thuộc của bên thứ 3.
Hàm này ghi RGBA
PNG , màu sắc trung thực (4 byte cho mỗi pixel) .
def write_png(buf, width, height):
""" buf: must be bytes or a bytearray in Python3.x,
a regular string in Python2.x.
"""
import zlib, struct
# reverse the vertical line order and add null bytes at the start
width_byte_4 = width * 4
raw_data = b''.join(
b'\x00' + buf[span:span + width_byte_4]
for span in range((height - 1) * width_byte_4, -1, - width_byte_4)
)
def png_pack(png_tag, data):
chunk_head = png_tag + data
return (struct.pack("!I", len(data)) +
chunk_head +
struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)))
return b''.join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
png_pack(b'IDAT', zlib.compress(raw_data, 9)),
png_pack(b'IEND', b'')])
... Dữ liệu phải được ghi trực tiếp vào tệp được mở dưới dạng nhị phân, như trong:
data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fh:
fh.write(data)
buf
) được cho là ở trong không? Nó dường như không phải là một mảng khó chịu ...
Có opencv
cho python ( tài liệu ở đây ).
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
hữu ích nếu bạn cần xử lý nhiều hơn ngoài việc tiết kiệm.
np.zeros((10,10))
bằng hình ảnh của bạn.
cmap="gray"
khi tôi lưu hình ảnh bằng cv2?
Nếu bạn có matplotlib, bạn có thể làm:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
plt.axis('off')
Bạn có thể sử dụng thư viện 'skimage' trong Python
Thí dụ:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
Phụ lục cho câu trả lời của @ ideaman42:
def saveAsPNG(array, filename):
import struct
if any([len(row) != len(array[0]) for row in array]):
raise ValueError, "Array should have elements of equal size"
#First row becomes top row of image.
flat = []; map(flat.extend, reversed(array))
#Big-endian, unsigned 32-byte integer.
buf = b''.join([struct.pack('>I', ((0xffFFff & i32)<<8)|(i32>>24) )
for i32 in flat]) #Rotate from ARGB to RGBA.
data = write_png(buf, len(array[0]), len(array))
f = open(filename, 'wb')
f.write(data)
f.close()
Vì vậy, bạn có thể làm:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
Sản xuất test_grid.png
:
(Tính minh bạch cũng hoạt động, bằng cách giảm byte cao từ 0xff
.)
Đối với những người tìm kiếm một ví dụ làm việc trực tiếp đầy đủ:
from PIL import Image
import numpy
w,h = 200,100
img = numpy.zeros((h,w,3),dtype=numpy.uint8) # has to be unsigned bytes
img[:] = (0,0,255) # fill blue
x,y = 40,20
img[y:y+30, x:x+50] = (255,0,0) # 50x30 red box
Image.fromarray(img).convert("RGB").save("art.png") # don't need to convert
Ngoài ra, nếu bạn muốn jpeg chất lượng cao
.save(file, subsampling=0, quality=100)
matplotlib svn có một chức năng mới để lưu hình ảnh chỉ là một hình ảnh - không có trục, v.v ... đó là một chức năng rất đơn giản để backport, nếu bạn không muốn cài đặt svn (được sao chép trực tiếp từ image.py trong matplotlib svn, hãy xóa doc Chuỗi cho ngắn gọn):
def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None):
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
canvas = FigureCanvas(fig)
fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin)
fig.savefig(fname, dpi=1, format=format)
Thế giới có lẽ không cần một gói nào khác để viết một mảng gọn gàng vào một tệp PNG, nhưng đối với những người không thể có đủ, gần đây tôi đã đưa lên numpngw
github:
https://github.com/WarrenWeckesser/numpngw
và trên pypi: https://pypi.python.org/pypi/numpngw/
Sự phụ thuộc bên ngoài duy nhất là numpy.
Đây là ví dụ đầu tiên từ examples
thư mục của kho lưu trữ. Dòng thiết yếu chỉ đơn giản là
write_png('example1.png', img)
nơi img
là một mảng NumPy. Tất cả mã trước dòng đó là nhập câu lệnh và mã để tạo img
.
import numpy as np
from numpngw import write_png
# Example 1
#
# Create an 8-bit RGB image.
img = np.zeros((80, 128, 3), dtype=np.uint8)
grad = np.linspace(0, 255, img.shape[1])
img[:16, :, :] = 127
img[16:32, :, 0] = grad
img[32:48, :, 1] = grad[::-1]
img[48:64, :, 2] = grad
img[64:, :, :] = 127
write_png('example1.png', img)
Đây là tệp PNG mà nó tạo:
Giả sử bạn muốn có một hình ảnh thang độ xám:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageio là một thư viện Python cung cấp giao diện dễ đọc và ghi nhiều loại dữ liệu hình ảnh, bao gồm hình ảnh hoạt hình, video, dữ liệu thể tích và các định dạng khoa học. Nó là đa nền tảng, chạy trên Python 2.7 và 3.4+ và rất dễ cài đặt.
Đây là ví dụ cho hình ảnh thang độ xám:
import numpy as np
import imageio
# data is numpy array with grayscale value for each pixel.
data = np.array([70,80,82,72,58,58,60,63,54,58,60,48,89,115,121,119])
# 16 pixels can be converted into square of 4x4 or 2x8 or 8x2
data = data.reshape((4, 4)).astype('uint8')
# save image
imageio.imwrite('pic.jpg', data)
Nếu bạn tình cờ sử dụng [Py] Qt, bạn có thể quan tâm đến qimage2ndarray . Bắt đầu với phiên bản 1.4 (vừa được phát hành), PySide cũng được hỗ trợ và sẽ có một imsave(filename, array)
chức năng nhỏ tương tự như scipy, nhưng sử dụng Qt thay vì PIL. Với 1.3, chỉ cần sử dụng một cái gì đó như sau:
qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..
(Một ưu điểm khác của 1.4 là nó là một giải pháp python thuần, làm cho nó thậm chí còn nhẹ hơn.)
Nếu bạn đang làm việc trong môi trường python Spyder, thì nó không thể dễ dàng hơn là chỉ cần nhấp chuột phải vào mảng trong trình thám hiểm biến, sau đó chọn tùy chọn Hiển thị hình ảnh.
Điều này sẽ yêu cầu bạn lưu hình ảnh vào dsik, chủ yếu ở định dạng PNG.
Thư viện PIL sẽ không cần thiết trong trường hợp này.
Sử dụng cv2.imwrite
.
import cv2
assert mat.shape[2] == 1 or mat.shape[2] == 3, 'the third dim should be channel'
cv2.imwrite(path, mat) # note the form of data should be height - width - channel
để lưu một mảng numpy như hình ảnh, U có một số lựa chọn:
1) tốt nhất khác: OpenCV
import cv2 cv2.imwrite('file name with extension(like .jpg)', numpy_array)
2) Matplotlib
from matplotlib import pyplot as plt plt.imsave('file name with extension(like .jpg)', numpy_array)
3) PIL
from PIL import Image image = Image.fromarray(numpy_array) image.save('file name with extension(like .jpg)')
4) ...