首页 > 解决方案 > Matplotlib 将黑白图像显示为灰色

问题描述

我有一个简单的代码来加载 RGB 图像,将其转换为灰度,然后运行 ​​Canny 边缘检测器算法。返回的图像仅包含 0 和 255 个值,但是当使用 matplotlib 显示图像时,它会将图像显示为灰度(而不是黑白)。

我怎样才能解决这个问题?

我的代码 -

import cv2
import matplotlib.pyplot as plt

in_img = cv2.imread('colored_image.jpeg')
gray_in_img = cv2.cvtColor(in_img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray_in_img, 100, 155)
fig = plt.figure(1)
ax = fig.add_subplot(1, 3, 1)
ax.imshow(cv2.cvtColor(in_img, cv2.COLOR_BGR2RGB))
ax = fig.add_subplot(1, 3, 2)
ax.imshow(gray_in_img, cmap='gray')
ax = fig.add_subplot(1, 3, 3)
ax.imshow(edges, cmap='gray')
plt.show()

输出图为:

RGB图像、灰度图像和边缘图像

放大最后一张图像,我们可以看到其中包含各种灰度强度,而不仅仅是黑白:

在此处输入图像描述

而我希望最后一张图像是黑白图像,例如:

在此处输入图像描述

当我调试代码时,我检查了 的值edges确实只有 0and 255

原始 RGB 图像:

在此处输入图像描述

标签: pythonmatplotlibedge-detectioncanny-operator

解决方案


图像只有edges黑白:

import numpy as np

np.unique(edges)
#array([  0, 255], dtype=uint8)

当您放大交互式后端时,您会看到边缘确实只有黑白。

默认情况下,imshow使用'antialiased'插值导致小比例图像的一些灰度值。您可以使用'none'or 'nearest'来防止这种情况:

ax.imshow(edges, cmap='gray', interpolation='nearest')

当您将图像保存为压缩格式(例如png)时,由于压缩,您还会在保存的图像中看到一些灰度值。您可以通过使用无损压缩或不压缩来防止这种情况发生,例如另存为tif或保存pngpil_kwargs={'compress_level': 0}.


根据以下评论中的讨论进行更新:
要查看具有纯黑白所有细节的完整精确图像,您需要缩放edges图像,以便 1 个图像像素 = 1 个显示像素(您可以使用它tkinter获取屏幕的 dpi 设置):

import tkinter
dpi = tkinter.Tk().winfo_fpixels('1i')

fig,ax = plt.subplots(dpi=dpi)
plt.axis('off')                                              # no ticks/tick labels
fig.subplots_adjust(0,0,1,1)                                 # no margins
fig.set_size_inches(edges.shape[1]/dpi, edges.shape[0]/dpi)  # 1 dot = 1 pixel
ax.imshow(edges, cmap='gray')

结果(以 100 % 的 Web 浏览器缩放比例查看)


推荐阅读