从 python 中的灰度热图创建多色阈值图像
create multi-colored thresholded image from grayscale heatmap in python
我有一个灰度图像,想在 4 个值范围(0.035、0.7、0.75)中对它们进行阈值处理,并以 4 种不同的颜色显示。我需要将结果保存为 UINT8 格式的图像。灰度图信息如下:
print(type(grads))
print(grads.shape)
print(grads.min())
print(grads.max())
cv2.imshow('1_grads', grads)
cv2.waitKey()
### OUTPUT
<class 'numpy.ndarray'>
(512, 512)
0.0
1.0
我试过以下方法:
thresh_map = Image.new('RGB', grads.shape, color='white')
thresh_map = np.where(grads < 0.035, (0, 0, 0), (0, 0, 0))
thresh_map = np.where(0.035 < grads < 0.7, (0, 0, 255), (0, 0, 0))
thresh_map = np.where(0.7 < grads < 0.75, (0, 255, 0), (0, 0, 0))
thresh_map = np.where(0.75 < grads, (0, 255, 0), (0, 0, 0))
这个 returns 这个错误:
ValueError: operands could not be broadcast together with shapes (512,512) (3,) (3,)
我已经通过使用 for 循环并一一粘贴像素值以某种方式解决了这个问题。但考虑到我要将其应用于 ~4000 张图像这一事实,它并不好并且需要很长时间。
thresh_map = Image.new('RGB', grads.shape, color='white')
blac = Image.new('RGB', (1, 1), color='black')
blue = Image.new('RGB', (1, 1), color='blue')
redd = Image.new('RGB', (1, 1), color='red')
gree = Image.new('RGB', (1, 1), color='green')
for i in range(grads.shape[0]):
for j in range(grads.shape[1]):
print(i, j)
if grads[i, j] < 0.035:
thresh_map.paste(blac, (i, j))
elif .035 < grads[i, j] < 0.7:
thresh_map.paste(redd, (i, j))
elif 0.7 < grads[i, j] < 0.75:
thresh_map.paste(gree, (i, j))
elif 0.75 < grads[i, j]:
thresh_map.paste(blue, (i, j))
np_thresh_map = np.asarray(thresh_map)
cv2.imshow('1_thresh', np_thresh_map)
cv2.waitKey()
是否有更复杂、更有效的方法?
这是我使用 NumPy boolean array indexing 的解决方案。代码应该简单明了。如果没有,请询问。然后我会提供更多的解释。
import cv2
import numpy as np
# Set up some random grayscale image; and sort for better visualization
image = np.sort(np.random.rand(300, 400))
# Given thresholds
thresholds = [0.035, 0.7, 0.75]
# Expand threshold with boundaries
thresholds = np.concatenate(([0], thresholds, [1]))
# Initialize output, and map colors
map = np.zeros((image.shape[0], image.shape[1], 3), np.uint8)
colors = np.array([[255, 0, 0], [128, 128, 0], [0, 0, 255], [0, 255, 0]])
# Iterate ranges; find proper pixel indices; set proper color in map at these indices
for i in range(len(thresholds)-1):
idx = (thresholds[i] <= image) & (image < thresholds[i+1])
map[idx, :] = colors[i, :]
# Show image and map
cv2.imshow('image', image)
cv2.imshow('map', map)
cv2.waitKey(0)
cv2.destroyAllWindows()
image
可能如下所示:
并且,相应的 map
看起来像这样:
希望对您有所帮助!
您可以使用 matplotlib 创建离散颜色图,使用 BoundaryNorm 作为标准化器:
import numpy as np
import matplotlib as mpl
import matplotlib.pylab as plt
#generate some data
dx, dy = 0.002, 0.002
y, x = np.mgrid[slice(0, 1 + dy, dy),
slice(0, 1 + dx, dx)]
z = np.sin(x)**1.5 + np.cos(10 + y*x) * np.cos(x)
z = z[:-1, :-1]/z.max()
#define colormap
cmap = matplotlib.colors.ListedColormap(["red", "blue", "green", "black"])
bounds = np.array([0,0.035,0.7,0.75,1])
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
#Plot
fig, axs = plt.subplots(figsize=(10, 10),nrows=2,ncols=1,gridspec_kw={'height_ratios': [20,1.5]})
pcm=axs[0].pcolormesh(x,y,z,cmap=cmap,norm=norm)
#colorbar
cbar=fig.colorbar(pcm,cax=axs[1], extend='both', orientation='horizontal')
这是结果:
编辑
要保存您的数据,您可以使用 matplotlib savefig function。如果你不想显示颜色条,你可以从上面的脚本中删除最后一行。您还可以使用以下方法删除刻度及其标签:
axs[0].get_xaxis().set_visible(False)
axs[0].get_yaxis().set_visible(False)
我有一个灰度图像,想在 4 个值范围(0.035、0.7、0.75)中对它们进行阈值处理,并以 4 种不同的颜色显示。我需要将结果保存为 UINT8 格式的图像。灰度图信息如下:
print(type(grads))
print(grads.shape)
print(grads.min())
print(grads.max())
cv2.imshow('1_grads', grads)
cv2.waitKey()
### OUTPUT
<class 'numpy.ndarray'>
(512, 512)
0.0
1.0
我试过以下方法:
thresh_map = Image.new('RGB', grads.shape, color='white')
thresh_map = np.where(grads < 0.035, (0, 0, 0), (0, 0, 0))
thresh_map = np.where(0.035 < grads < 0.7, (0, 0, 255), (0, 0, 0))
thresh_map = np.where(0.7 < grads < 0.75, (0, 255, 0), (0, 0, 0))
thresh_map = np.where(0.75 < grads, (0, 255, 0), (0, 0, 0))
这个 returns 这个错误:
ValueError: operands could not be broadcast together with shapes (512,512) (3,) (3,)
我已经通过使用 for 循环并一一粘贴像素值以某种方式解决了这个问题。但考虑到我要将其应用于 ~4000 张图像这一事实,它并不好并且需要很长时间。
thresh_map = Image.new('RGB', grads.shape, color='white')
blac = Image.new('RGB', (1, 1), color='black')
blue = Image.new('RGB', (1, 1), color='blue')
redd = Image.new('RGB', (1, 1), color='red')
gree = Image.new('RGB', (1, 1), color='green')
for i in range(grads.shape[0]):
for j in range(grads.shape[1]):
print(i, j)
if grads[i, j] < 0.035:
thresh_map.paste(blac, (i, j))
elif .035 < grads[i, j] < 0.7:
thresh_map.paste(redd, (i, j))
elif 0.7 < grads[i, j] < 0.75:
thresh_map.paste(gree, (i, j))
elif 0.75 < grads[i, j]:
thresh_map.paste(blue, (i, j))
np_thresh_map = np.asarray(thresh_map)
cv2.imshow('1_thresh', np_thresh_map)
cv2.waitKey()
是否有更复杂、更有效的方法?
这是我使用 NumPy boolean array indexing 的解决方案。代码应该简单明了。如果没有,请询问。然后我会提供更多的解释。
import cv2
import numpy as np
# Set up some random grayscale image; and sort for better visualization
image = np.sort(np.random.rand(300, 400))
# Given thresholds
thresholds = [0.035, 0.7, 0.75]
# Expand threshold with boundaries
thresholds = np.concatenate(([0], thresholds, [1]))
# Initialize output, and map colors
map = np.zeros((image.shape[0], image.shape[1], 3), np.uint8)
colors = np.array([[255, 0, 0], [128, 128, 0], [0, 0, 255], [0, 255, 0]])
# Iterate ranges; find proper pixel indices; set proper color in map at these indices
for i in range(len(thresholds)-1):
idx = (thresholds[i] <= image) & (image < thresholds[i+1])
map[idx, :] = colors[i, :]
# Show image and map
cv2.imshow('image', image)
cv2.imshow('map', map)
cv2.waitKey(0)
cv2.destroyAllWindows()
image
可能如下所示:
并且,相应的 map
看起来像这样:
希望对您有所帮助!
您可以使用 matplotlib 创建离散颜色图,使用 BoundaryNorm 作为标准化器:
import numpy as np
import matplotlib as mpl
import matplotlib.pylab as plt
#generate some data
dx, dy = 0.002, 0.002
y, x = np.mgrid[slice(0, 1 + dy, dy),
slice(0, 1 + dx, dx)]
z = np.sin(x)**1.5 + np.cos(10 + y*x) * np.cos(x)
z = z[:-1, :-1]/z.max()
#define colormap
cmap = matplotlib.colors.ListedColormap(["red", "blue", "green", "black"])
bounds = np.array([0,0.035,0.7,0.75,1])
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
#Plot
fig, axs = plt.subplots(figsize=(10, 10),nrows=2,ncols=1,gridspec_kw={'height_ratios': [20,1.5]})
pcm=axs[0].pcolormesh(x,y,z,cmap=cmap,norm=norm)
#colorbar
cbar=fig.colorbar(pcm,cax=axs[1], extend='both', orientation='horizontal')
这是结果:
编辑 要保存您的数据,您可以使用 matplotlib savefig function。如果你不想显示颜色条,你可以从上面的脚本中删除最后一行。您还可以使用以下方法删除刻度及其标签:
axs[0].get_xaxis().set_visible(False)
axs[0].get_yaxis().set_visible(False)