Có thể có những cách tốt hơn để làm điều này; Tôi không chắc. Nếu bạn đọc help(cm.jet)
, bạn sẽ thấy thuật toán được sử dụng để ánh xạ các giá trị trong khoảng [0,1] đến RGB 3-tuple. Bạn có thể, với một tờ giấy nhỏ và bút chì, làm việc ra công thức để đảo ngược các chức năng piecewise-tuyến tính mà xác định các bản đồ.
Tuy nhiên, có một số vấn đề mà làm cho giấy và bút chì giải pháp nào không hấp dẫn:
Đó là rất nhiều đại số khó nhọc, và giải pháp cụ thể cho cm.jet. Bạn sẽ phải thực hiện lại tất cả công việc này nếu bạn thay đổi bản đồ màu. Làm thế nào để tự động hoá việc giải quyết các phương trình đại số là thú vị, nhưng không phải là một vấn đề tôi biết làm thế nào để giải quyết.
Nói chung, bản đồ màu có thể không được không thể đảo ngược (nhiều giá trị có thể được ánh xạ tới cùng một màu). Trong trường hợp của cm.jet, các giá trị giữa 0,11 và 0,125 đều được ánh xạ tới RGB 3-tuple (0,0,1) chẳng hạn. Vì vậy, nếu hình ảnh của bạn chứa một màu xanh lam pixel, thực sự không có cách nào để cho biết liệu hình ảnh đó có đến giá trị 0,11 hoặc giá trị là 0,125 hay không.
- Ánh xạ từ [0,1] đến 3-tuple là đường cong trong không gian 3 chiều. Các màu trong hình ảnh của bạn có thể không nằm ở hoàn hảo trên đường cong này. Ví dụ: có thể có là lỗi làm tròn. Vì vậy, bất kỳ giải pháp thực tế nào để có thể nội suy hoặc bằng cách nào đó dự án điểm trong không gian 3 vào đường cong.
Do vấn đề không phải là duy nhất và vấn đề về phép chiếu/nội suy, có thể có nhiều giải pháp khả thi cho vấn đề bạn đặt ra. Dưới đây chỉ là một khả năng.
Dưới đây là một cách để giải quyết vấn đề độc đáo và chiếu/nội suy:
Tạo một gradient
đóng vai trò như một "cuốn sách mã". gradient
là một mảng RGBA 4-tuples trong bản đồ màu cm.jet. Các màu của gradient
tương ứng với các giá trị từ 0 đến 1. Sử dụng chức năng lượng tử vector của scipy scipy.cluster.vq.vq để ánh xạ tất cả các màu trong hình ảnh của bạn, mri_demo.png, lên màu gần nhất trong gradient
. Vì bản đồ màu có thể sử dụng cùng một màu cho nhiều giá trị, độ dốc có thể chứa màu trùng lặp. Tôi để nó lên đến scipy.cluster.vq.vq
để quyết định (có thể) chỉ mục mã sách không duy nhất nào liên kết với một màu cụ thể.
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import scipy.cluster.vq as scv
def colormap2arr(arr,cmap):
# http://stackoverflow.com/questions/3720840/how-to-reverse-color-map-image-to-scalar-values/3722674#3722674
gradient=cmap(np.linspace(0.0,1.0,100))
# Reshape arr to something like (240*240, 4), all the 4-tuples in a long list...
arr2=arr.reshape((arr.shape[0]*arr.shape[1],arr.shape[2]))
# Use vector quantization to shift the values in arr2 to the nearest point in
# the code book (gradient).
code,dist=scv.vq(arr2,gradient)
# code is an array of length arr2 (240*240), holding the code book index for
# each observation. (arr2 are the "observations".)
# Scale the values so they are from 0 to 1.
values=code.astype('float')/gradient.shape[0]
# Reshape values back to (240,240)
values=values.reshape(arr.shape[0],arr.shape[1])
values=values[::-1]
return values
arr=plt.imread('mri_demo.png')
values=colormap2arr(arr,cm.jet)
# Proof that it works:
plt.imshow(values,interpolation='bilinear', cmap=cm.jet,
origin='lower', extent=[-3,3,-3,3])
plt.show()
Hình ảnh mà bạn nhìn thấy nên được gần gũi với tái tạo mri_demo.png:
(Các mri_demo.png ban đầu có đường viền màu trắng Kể từ trắng không phải là một màu trong cm.jet. , lưu ý rằng scipy.cluster.vq.vq
đồ trắng để đến thời điểm gần nhất trong cuốn sách gradient
mã, mà sẽ xảy ra là một màu xanh nhạt.)
vâng, đây thực chất là điều tôi nghĩ là có thể. Giải pháp ban đầu của bạn bao gồm đọc một dòng từ một hình ảnh với cùng một bản đồ màu, điều này có thể hữu ích cho những người nói, quét một hình trong và muốn thực hiện phân tích số riêng của họ. Tôi đã gặp khó khăn trong việc lượng tử hóa vector - ban đầu, có vẻ như đặt cược tốt nhất là chu kỳ qua từng màu có thể trong lut và tính khoảng cách 3d từ giá trị pixel thực tế - mà tôi không thể biết cách làm nhanh vòng lặp. Cảm ơn! – user448764