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:
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.