首页 > 解决方案 > 从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))

这将返回此错误: 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()

在此处输入图像描述

有没有更复杂和有效的方法来做到这一点?

标签: pythonopencvpython-imaging-librarythresholdimage-thresholding

解决方案


这是我使用 NumPy 的布尔数组索引的解决方案。代码应该很简单。如果没有,请询​​问。然后,我将提供更多解释。

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看起来像这样:

地图

希望有帮助!


推荐阅读