50

Tôi có một vấn đề đơn giản nhưng không thể tìm thấy một giải pháp tốt cho nó.Làm thế nào để chuyển đổi mảng Numpy sang hình ảnh PIL áp dụng matplotlib colormap

Tôi muốn lấy một mảng 2D dạng khối đại diện cho hình ảnh thang độ xám và chuyển đổi hình ảnh thành hình ảnh RGB PIL trong khi áp dụng một số bản đồ màu matplotlib.

tôi có thể có được một sản lượng PNG hợp lý bằng công pyplot.figure.figimage lệnh:

dpi = 100.0 
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi 
fig = plt.figure(figsize=(w,h), dpi=dpi) 
fig.figimage(sub, cmap=cm.gist_earth) 
plt.savefig('out.png') 

Mặc dù tôi có thể thích ứng này để có được những gì tôi muốn (có thể sử dụng StringIO làm có được hình ảnh PIL), tôi tự hỏi nếu có không phải là một cách đơn giản hơn để làm điều đó, vì nó có vẻ là một vấn đề rất tự nhiên về trực quan hóa hình ảnh. Giả sử như sau:

colored_PIL_image = magic_function(array, cmap) 

Cảm ơn bạn đã đọc!

+0

Đối với mã hoạt động đầy đủ, bạn có thể tham khảo: [Có bản đồ màu nào tốt để chuyển đổi hình ảnh có tỷ lệ màu xám thành hình ảnh đầy màu sắc bằng cách sử dụng PIL của python không?] (Http://stackoverflow.com/questions/43457308/is-there-any- color-color-map-to-convert-gray-scale-image-to-colorful-ones-using-p) – Adam

Trả lời

99

Khá bận rộn lót, nhưng ở đây nó là:

  1. Đầu tiên đảm bảo mảng NumPy của bạn, myarray, là bình thường với giá trị tối đa tại 1.0.
  2. Áp dụng bản đồ màu trực tiếp lên myarray.
  3. Rescale đến phạm vi 0-255.
  4. Chuyển đổi thành số nguyên, sử dụng np.uint8().
  5. Sử dụng Image.fromarray().

Và bạn đã hoàn tất:

from PIL import Image 
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255)) 

với plt.savefig():

enter image description here

với im.save():

enter image description here

+4

"Áp dụng bản đồ màu trực tiếp vào phần" myarray "được cắt thẳng vào tim! Tôi không biết điều đó là có thể, cảm ơn bạn! – heltonbiker

+0

@heltonbiker - vâng, nó khá thú vị;) – fraxel

+27

Nghiên cứu tài liệu về LinearSegmentedColormap (từ đó cm.gist_earth là một thể hiện), tôi phát hiện ra rằng có thể gọi nó bằng đối số "byte" đã chuyển đổi thành uint8. Sau đó, một lớp lót trở nên yên lặng hơn nhiều: 'im = Image.fromarray (cm.gist_earth (myarray, bytes = True))' – heltonbiker

Các vấn đề liên quan