Zorro
Zorro

Reputation: 1519

How to convert binary matplotlib to binary numpy array?

I'm trying to plot x and y list then convert it to numpy array but with 0 and 255 value only, black and white.

So i tried this , it's working but i got an array with intermediary colors:

print(np.unique(data))
[0 1 2 3 4 5 6 7 8 9 10 11 ... 255]

So my solution for now is:

import numpy as np
import cv2
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

input_file = "image.png"
fig = plt.figure()

# drawn points
x = [1,2,3,4]
y = [1,2,3,4]

plt.axis('off')
plt.plot(x, y, color='black', linewidth=1)
plt.savefig(f"{input_file}.IMG.png", dpi=100)

def plot2Grayscale(image):
    im = cv2.imread(image) 
    gray= cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    cmap = ListedColormap(['black', 'white'])
    plt.imsave(image, gray, cmap = cmap)        
    gray = cv2.imread(image, 0)
    return gray

data = plot2Grayscale(f"{input_file}.IMG.png")
print(np.unique(data))

[0 255]

What i'm asking is there is a way to got the binary array from plot without having to save it then read it like i did?

Upvotes: 0

Views: 280

Answers (1)

LGrementieri
LGrementieri

Reputation: 800

You are close to the solution and the linked answer is almost sufficient to do what you ask, you just need to disable the anti-aliasing in plt.plot.

The following code should work

import numpy as np
import matplotlib.pyplot as plt

# drawn points
x = [1,2,3,4]
y = [1,2,3,4]

fig = plt.figure()
plt.axis('off')

# Use antialised=False instead of the default antialiased=True
plt.plot(x, y, color='black', antialiased=False, linewidth=1)
fig.canvas.draw()

# Covert the plot to a numpy array
data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))

# Check that the produced array contains 0 and 255 only
print(np.unique(data))

Sidenote: the linked answer uses np.fromstring that is now deprecated in favor of np.frombuffer.

Upvotes: 1

Related Questions