简体   繁体   中英

Matplotlib shows black & white image as gray

I have a simple code that loads RGB image, converts it to grayscale and then runs Canny edge detector algorithm. The returned image contains only 0 and 255 values, and yet when showing the image using matplotlib it shows the image as grayscale (and not black and white).

How can I fix this?

My code -

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()

The output figure is:

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

Zooming in the last image we can see that in contains variety of gray intensities instead of black and white only:

在此处输入图片说明

whereas I'd like the last image to be a black and white image, such as:

在此处输入图片说明

When I've debugged the code, I've checked that the values of edges are indeed only 0 and 255 .

The original RGB image:

在此处输入图片说明

The edges image is black and white only:

import numpy as np

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

When you zoom in on the interactive backend, you'll see that the edges are indeed black and white only.

By default, imshow uses 'antialiased' interpolation which leads to some gray values for small scale images. You can use 'none' or 'nearest' instead to prevent this:

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

When you save the image to a compressed format (eg png ) you'll also see some gray values in the saved image due to compression. You can prevent this by using a lossless compression or no compression, eg save as tif or as png with pil_kwargs={'compress_level': 0} .

I would suggest setting the interpolation keyword argument in the ax.imshow() method to "none" , and enlarging the subplots with the figsize keyword argument to show more details:

import cv2
import matplotlib.pyplot as plt

in_img = cv2.imread('colored_image.png')
gray_in_img = cv2.cvtColor(in_img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray_in_img, 100, 155)
fig = plt.figure(1, figsize=(16, 5))

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)
fig.tight_layout()
ax.imshow(edges, cmap='gray', interpolation="none")
plt.show()

Output (the third image might still seem gray, but that's the anti aliasing from your browser; click to see the image in large) :

在此处输入图片说明

Note the fig.tight_layout() line I added to have the subplots a bit larger.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM