Eliminar el borde blanco alrededor de una imagen cuando se usa matplot

Eliminar el borde blanco alrededor de una imagen cuando se usa matplotlib sin guardar la imagen

Tengo el siguiente código:

#load in image
image = cv2.imread('lenna.png')
title = "foo"

ax = plt.axes([0,0,1,1])
ax.clear()
height, width = image.shape[:2]
ax.axis('off')
ax.set_title(title)

#some things plotted etc.

Pero luego necesito la figura como matriz numpy para realizar más cálculos, así que hago lo siguiente:

masked_image = image
ax.imshow(masked_image.astype(np.uint8),interpolation="nearest")
ax.figure.canvas.draw()
w,h = ax.figure.get_size_inches()*ax.figure.get_dpi()
I = np.fromstring(ax.figure.canvas.tostring_rgb(),dtype=np.uint8).reshape(int(h),int(w),3)

#Has the white borders around it
Image.fromarray(I)

Sin embargo, I todavía tiene bordes blancos a su alrededor, ¿hay alguna manera fácil de eliminar los bordes blancos sin guardar la figura?

La imagen que utilicé es la siguiente:

ingrese la descripción de la imagen aquí

que no tiene bordes blancos alrededor

Sin embargo, después del código anterior, se parece a lo siguiente: ingrese la descripción de la imagen aquí

Que ahora tiene barras blancas alrededor.

Otra solución ya publicada para esto se basa en guardar la imagen, lo cual no quiero

Mostrar la mejor respuesta

Su código no está completo stackoverflow.com/help/mcve. Hace que sea difícil de reproducir.

@FHTMitchell, gracias, edité la pregunta.

Es un poco difícil de entender por qué harías eso. image es una matriz numpy ya. ¿Por qué producir un gráfico y guardarlo como una matriz numpy nuevamente?

Lo dejé fuera, porque no está realmente relacionado con la pregunta. Se agregarán texto y cuadros delimitadores a la trama con la ayuda de matplotlib.

En realidad no importa si guardas la figura o no. Hay dos condiciones que deben cumplirse para no tener espacios en blanco alrededor de una imagen.

1. Márgenes de figuras

No debe haber espacio entre los ejes y el borde de la figura. Esto se puede lograr configurando los parámetros de subtrama

fig, ax = plt.subplots()
fig.subplots_adjust(0,0,1,1)

o configurando manualmente la posición de los ejes

fig= plt.figure()
fig.add_axes([0,0,1,1])

Este último es el enfoque que tomó en la pregunta, por lo que esta parte está bien.

2. El aspecto de la figura

Las imágenes se muestran con el mismo aspecto, lo que significa que cada píxel está cuadrado. Esto suele ser deseable para las imágenes, pero hace que los ejes no se expandan en ambas direcciones por igual.
El problema al que te enfrentas aquí se debe a que la figura tiene un aspecto diferente al de la imagen.

Supongamos que tiene una imagen de forma (n,m) (m píxeles de ancho, n píxeles de alto); entonces la condición necesaria para que no haya espacios en blanco alrededor de su imagen es que

n/m == h/w

donde w, h son el ancho y alto de la figura, respectivamente.

Por lo tanto, puede establecer directamente el tamaño de la figura en la forma de la matriz multiplicada por los ppp,

fig, ax = plt.subplots(figsize=(m*100,n*100), dpi=100)

o cualquier otro múltiplo en caso de que no necesite tener un píxel por píxel en la salida. En caso de que no le importe en absoluto el tamaño de la figura, pero aún necesita una figura con el mismo aspecto que la imagen, puede usar figaspect

figsize=plt.figaspect(image)

Para proporcionar ejemplos de trabajo completos aquí, lo siguiente crea una figura con una imagen que no tiene espacios en blanco alrededor.

import matplotlib.pyplot as plt
import numpy as np

a = np.random.rand(5,3)

fig, ax = plt.subplots(figsize=plt.figaspect(a))
fig.subplots_adjust(0,0,1,1)
ax.imshow(a)

plt.show()