Siddharth Satpathy
Siddharth Satpathy

Reputation: 3043

How to save grayscale image in Python?

I am trying to save a grayscale image using matplotlib savefig(). I find that the png file which is saved after the use of matplotlib savefig() is a bit different from the output image which is showed when the code runs. The output image which is generated when the code is running contains more details than the saved figure.

How can I save the output plot in such a manner that all details are stored in the output image?

My my code is given below:

import cv2
import matplotlib.pyplot as plt

plt.figure(1)
img_DR = cv2.imread(‘image.tif',0)
edges_DR = cv2.Canny(img_DR,20,40)
plt.imshow(edges_DR,cmap = 'gray')
plt.savefig('DR.png')
plt.show()

The input file (‘image.tif’) can be found from here.

Following is the output image which is generated when the code is running:

enter image description here

Below is the saved image:

enter image description here

Although the two aforementioned images denote the same picture, one can notice that they are slightly different. A keen look at the circular periphery of the two images shows that they are different.

Upvotes: 1

Views: 26381

Answers (3)

Steve
Steve

Reputation: 1188

Since you are using cv2 to load the image, why not using it also to save it. I think the command you are looking for is :

cv2.imwrite('gray.jpg', gray_image)

Upvotes: 5

Prasanth
Prasanth

Reputation: 412

Using a DPI that matches the image size seems to make a difference.

The image is of size width=2240 and height=1488 (img_DR.shape). Using fig.get_size_inches() I see that the image size in inches is array([7.24, 5.34]). So an appropriate dpi is about 310 since 2240/7.24=309.4 and 1488/5.34=278.65.

Now I do plt.savefig('DR.png', dpi=310) and get

DPI=310 image

One experiment to do would be to choose a high enough DPI, calculate height and width of figure in inches, for example width_inch = width_pixel/DPI and set figure size using plt.figure(figsize=(width_inch, height_inch)), and see if the displayed image itself would increase/decrease in quality.

Hope this helps.

Upvotes: 1

rayryeng
rayryeng

Reputation: 104555

Save the actual image to file, not the figure. The DPI between the figure and the actual created image from your processing will be different. Since you're using OpenCV, use cv2.imwrite. In your case:

cv2.imwrite('DR.png', edges_DR)

Use the PNG format as JPEG is lossy and would thus give you a reduction in quality to promote small file sizes. If accuracy is the key here, use a lossless compression standard and PNG is one example.


If you are somehow opposed to using OpenCV, Matplotlib has an equivalent image writing method called imsave which has the same syntax as cv2.imwrite:

plt.imsave('DR.png', edges_DR, cmap='gray')

Note that I am enforcing the colour map to be grayscale for imsave as it is not automatically inferred like how OpenCV writes images to file.

Upvotes: 10

Related Questions