写下我自己的图像功能,该功能将灰度(0-255)到ar,g,b,alpha热图

发布于 2025-02-05 04:27:14 字数 883 浏览 2 评论 0原文

我有一个300*500图像。它在灰度,范围为0-255。我想按值迭代价值,并将热图(例如Viridis)应用于每个值。

我的最终热图图像是红色,蓝色,绿色和alpha。我想特定的热图功能将对每个红色,蓝色,绿色及其适当的权重输出三个值。

f(0-255)= comatetr (红色), stogeb (蓝色), strogeg (绿色)。

我的结局图像将具有尺寸(300,500,4),四个通道是R,B,G和Alpha通道。

可以实现这一目标的功能是什么?几乎可以肯定的是,它将高度依赖于特定的热图。 Viridis就是我所追求的,但我也想了解这个概念。

下面的代码在随机图像中读取(事实是从Unsplash无关紧要的),并将其变成(300,500),0-255图像,称为 imgarray 。我知道Matplotlib默认为Viridis,但我包括了额外的步骤,以显示我想通过自己的功能实现的目标。

import matplotlib.pyplot as plt
import requests
from PIL import Image
from io import BytesIO

img_src = 'https://unsplash.it/500/300'
response = requests.get(img_src)
imgarray = Image.open(BytesIO(response.content))
imgarray = np.asarray(imgarray.convert('L'))
from matplotlib import cm
print(cm.viridis(imgarray))
plt.imshow(cm.viridis(imgarray))

I have a 300*500 image. It's is in grayscale and ranges from 0-255. I want to iterate value by value and apply a heat map (say viridis but it doesn't matter) to each value.

My final heatmap image is in Red, Blue, Green and Alpha. I imagine the specific heat map function would take the grayscale values and output three values for each Red, Blue, Green and their appropriate weights.

f(0-255) = weightr(Red), weightb(Blue), weightg(Green).

My ending image would have dimensions (300,500,4) The four channels are r,b,g and an alpha channel.

What is the function that would achieve this? Almost certain it's going to be highly dependent on the specific heat map. Viridis is what I'm after, but I want to understand the concept as well.

The code below reads in a random image (the fact it's from unsplash does not matter) and turns it into a (300,500), 0-255 image called imgarray. I know matplotlib defaults to viridis, but I included the extra step to show what I would like to achieve with my own function.

import matplotlib.pyplot as plt
import requests
from PIL import Image
from io import BytesIO

img_src = 'https://unsplash.it/500/300'
response = requests.get(img_src)
imgarray = Image.open(BytesIO(response.content))
imgarray = np.asarray(imgarray.convert('L'))
from matplotlib import cm
print(cm.viridis(imgarray))
plt.imshow(cm.viridis(imgarray))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

女皇必胜 2025-02-12 04:27:14

Matplotlib将Viridis Colormap定义为256 RGB颜色(每个8位灰度值),其中每个颜色通道都是[0,1]的浮点值。该定义可以在。以下代码演示了Matplotlib如何将Viridis Colormap应用于灰度图像。

import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib._cm_listed import _viridis_data  # the colormap look-up table
import requests
from PIL import Image
from io import BytesIO

img_src = 'https://unsplash.it/id/767/500/300'
response = requests.get(img_src)
imgarray = Image.open(BytesIO(response.content))
imgarray = np.asarray(imgarray.convert('L'))

plt.imshow(cm.viridis(imgarray))
plt.show()

# look-up table: from grayscale to RGB
viridis_lut = np.array(_viridis_data)
print(viridis_lut.shape)  # (256, 3)

# convert grayscale to RGB using the LUT
img_viridis = viridis_lut.take(imgarray, axis=0, mode='clip')
plt.imshow(img_viridis)
plt.show()

# add an alpha channel
alpha = np.full(imgarray.shape + (1,), 1.)  # shape: (300, 500, 1)
img_viridis_alpha = np.concatenate((img_viridis, alpha), axis=2)

assert (cm.viridis(imgarray) == img_viridis_alpha).all()  # are both equal

产生以下图像:

“

实际魔术发生在np.take(a,indices)方法中,该方法从数组中获取值a( viridis lut)在给定的indices(图像从0..255发出的灰度值)。要获得与cm.viridis函数相同的结果,我们只需要添加一个alpha频道(满是1。 =完全不透明度)。

为了参考,相同的转换发生在matplotlib源代码中。

Matplotlib defines the viridis colormap as 256 RGB colors (one for each 8 bit gray scale value), where each color channel is a floating point value from [0, 1]. The definition can be found on github. The following code demonstrates how matplotlib applies the viridis colormap to a gray scale image.

import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib._cm_listed import _viridis_data  # the colormap look-up table
import requests
from PIL import Image
from io import BytesIO

img_src = 'https://unsplash.it/id/767/500/300'
response = requests.get(img_src)
imgarray = Image.open(BytesIO(response.content))
imgarray = np.asarray(imgarray.convert('L'))

plt.imshow(cm.viridis(imgarray))
plt.show()

# look-up table: from grayscale to RGB
viridis_lut = np.array(_viridis_data)
print(viridis_lut.shape)  # (256, 3)

# convert grayscale to RGB using the LUT
img_viridis = viridis_lut.take(imgarray, axis=0, mode='clip')
plt.imshow(img_viridis)
plt.show()

# add an alpha channel
alpha = np.full(imgarray.shape + (1,), 1.)  # shape: (300, 500, 1)
img_viridis_alpha = np.concatenate((img_viridis, alpha), axis=2)

assert (cm.viridis(imgarray) == img_viridis_alpha).all()  # are both equal

Produces the following image:

Viridis colormap applied

The actual magic happens in the np.take(a, indices) method, which takes values from array a (the viridis LUT) at the given indices (gray scale values from 0..255 from the image). To get the same result as from the cm.viridis function, we just need to add an alpha channel (full of 1. = full opacity).

For reference, the same conversion happens around here in the matplotlib source code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文