在不保存图像的情况下使用 matplotlib 时移除图像周围的白色边框

Kev*_*n91 7 python matplotlib

我有以下代码:

#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.
Run Code Online (Sandbox Code Playgroud)

但是随后我需要将该图作为 numpy 数组进行进一步计算,因此我正在执行以下操作:

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)
Run Code Online (Sandbox Code Playgroud)

但是, I 现在它周围仍然有白色边框,有没有一种简单的方法可以在不保存图形的情况下去除白色边框?

我使用的图像如下:

在此处输入图片说明

它周围没有任何白色边框

但是在上面的代码之后,它看起来像下面这样: 在此处输入图片说明

现在它周围有白条。

其他已经发布的解决方案都依赖于保存图像,这是我不想要的

Imp*_*est 7

是否保存图形实际上并不重要。要使图像周围没有空格,需要满足两个条件。

1. 图边距

您需要在轴和图形边缘之间没有空间。这可以通过设置子图参数来实现

fig, ax = plt.subplots()
fig.subplots_adjust(0,0,1,1)
Run Code Online (Sandbox Code Playgroud)

或通过手动设置轴位置

fig= plt.figure()
fig.add_axes([0,0,1,1])
Run Code Online (Sandbox Code Playgroud)

后者是你在问题中采用的方法,所以这部分很好。

2.图形方面

图像以相同的方面显示,这意味着每个像素都是平方的。这通常是图像所需要的,但它会导致轴不会向两个方向均匀扩展。
您在这里面临的问题是由与图像具有不同方面的图形引起的。

假设您有一个形状图像(n,m)m像素宽,n像素高);那么在图像周围没有空白的必要条件是

n/m == h/w
Run Code Online (Sandbox Code Playgroud)

其中wh分别是图形的宽度和高度。

因此,您可以直接将图形大小设置为数组形状乘以 dpi,

fig, ax = plt.subplots(figsize=(m*100,n*100), dpi=100)
Run Code Online (Sandbox Code Playgroud)

或任何其他倍数,以防您不需要在输出中每个像素有一个像素。如果您根本不关心图形大小,但仍然需要与您可能使用的图像具有相同外观的图形figaspect

figsize=plt.figaspect(image)
Run Code Online (Sandbox Code Playgroud)

为了在此处提供完整的工作示例,以下创建了一个图形,其中包含一个周围没有空白的图像。

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()
Run Code Online (Sandbox Code Playgroud)