Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing the white border around an image when using matplotlib without saving the image

I have the following code:

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

But then I need the figure as numpy array for further computation, so I am doing the following:

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)

However, I still has now white borders around it, is there an easy way to remove the white borders without saving the figure?

The image I used is the following:

enter image description here

which does not have any white borders around it

However after the code above, it looks like the following: enter image description here

Which now has white bars around it.

Other already posted solution to this are all relying on saving the image, which I do not want

like image 984
Kev1n91 Avatar asked Apr 06 '18 13:04

Kev1n91


People also ask

How do I get rid of whitespace in matplotlib?

To remove whitespaces at the bottom of a Matplotlib graph, we can use tight layout or autoscale_on=False.

How do I save a matplotlib plot without white space?

Hide the Whitespaces and Borders in Matplotlib Figure To get rid of whitespace around the border, we can set bbox_inches='tight' in the savefig() method. Similarly, to remove the white border around the image while we set pad_inches = 0 in the savefig() method.

How do I remove a border in Python?

Set the size of the frame using root. Next, create a Canvas and set the border width of the canvas with "bd" attribute. Then, use the "highlightthickness" attribute to define whether you want to show the canvas border or not. Set "highlightthickness=0" in case you want to get rid of the canvas border.


1 Answers

It doesn't actually matter if you save the figure or not. There are two conditions that need to be fulfilled to have no whitespace around an image.

1. Figure margins

You need to have no space between axes and figure edge. This can be achieved via setting the subplot params

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

or by manually setting the axes position

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

The latter is the approach you took in the question, so this part is fine.

2. The figure aspect

Images are shown with an equal aspect, which means that each pixel is squared. This is usually desired for images, but it leads to axes not expanding to both directions equally.
The problem you face here is caused by the figure having a different aspect than the image.

Say you have an image of shape (n,m) (m pixels wide, n pixels high); then the necessary condition to get no whitespace around your image is that

n/m == h/w

where w, h are the figure width and height, respectively.

So you may directly set the figure size to the array shape times the dpi,

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

or any other multiple in case you do not need to have one pixel per pixel in the output. In case you do not care about the figure size at all, but still need a figure with the same aspect as the image you may use figaspect

figsize=plt.figaspect(image)

To provide a full working examples here, the following creates a figure with an image which has no whitespace around it.

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()
like image 109
ImportanceOfBeingErnest Avatar answered Sep 20 '22 16:09

ImportanceOfBeingErnest