Convert Matplotlib figure to NumPy array without a

2020-07-17 08:38发布

问题:

I'm trying to compare a generated image in Python with an image/photo in a file.

The best way I got to make this so far is by generating a figure in Matplotlib and then convert it to a numpy array and compare the values with the values I get from my image.

I got the following code to convert a Matplotlib figure to a 3D numpy array with RGB channels:

def fig2data ( fig ):
    """
    @brief Convert a Matplotlib figure to a 3D numpy array with RGB channels and return it
    @param fig a matplotlib figure
    @return a numpy 3D array of RGB values
    """
    # draw the renderer
    fig.canvas.draw ( )

    # Get the RGBA buffer from the figure
    w,h = fig.canvas.get_width_height()
    buf = numpy.fromstring ( fig.canvas.tostring_rgb(), dtype=numpy.uint8 )
    buf.shape = ( w, h, 3 )

    return buf

One of the problems - the one I'm trying to figure out so far - is that this converted image doesn't come croped. For instance, if I draw a square ocupying the all canvas, Matplotlib put's this anoying frame arround and that is converted and mixes all my results.

How do I get only the numeric values - without any frame or axis - of the figure I made?

Or even better, if there is a much easier way to compare the figure and the image in NumPy/Matplotlib that I don't know about, please do let me know.

回答1:

Well, it's not really an answer to the problem at hand using Matplotlib, but I gave up on this lib for this job and just used PIL.

It's quite easy, altough it's also quite slow (but I don't know if it's slower than Matplotlib).

The code is the following:

def makeImage (triangle, largura, altura):
    """
    triangle: receives a tuple in the form: x1, y1, x2, y2, x3, y3, R, G, B, A
    largura: image weight
    altura: image height

    returns: numPy array of the triangle composed final image
    """
    back = Image.new('RGBA', (largura,altura), (0,0,0,0))
    poly = Image.new('RGBA', (largura,altura))
    pdraw = ImageDraw.Draw(poly)

    pdraw.polygon([1,2,3,4,5,6], fill=(255,0,0,127))
    back.paste(poly,mask=poly)

    back = back.convert('RGB')
    backArr = asarray(back)
    #back.show()

    return backArr

If you know of a way to speed up this process, please do let me know.