Save image without rescaling - python

I have a 2D array and I need to save it as an image. What's the best way to do it without rescaling? I want to read the image afterwards and check that the values have been saved correctly. I am saving it as a bmp so to avoid compression issues, but other formats should also be fine.

To save an image you can use SciPys imsave function.
imsave(path, image)
EDIT: To Save an image as bmp just choose the file extension in path accordingly.
EDIT2: To prevent intensity normalization you can use
scipy.toimage(image, cmin=0, cmax=255, mode='I').save("image.png")
You can use mode'I'to save your image in a specific format. Just be sure that your input is of type uint16.

Related

Convert pyglet ColorBufferImage into PIL format

I have a small animation (pyglet) that I am taking a screenshot of that I want to use in a CNN afterwards. At the moment, I have to save a screenshot (ColorBufferImage) and then upload it again directly so that the image is in the correct format for the CNN (PIL format).
For better performance I would skip the whole thing without having to save the image extra. Here is my code:
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png')
image = tensorflow.keras.utils.load_img('screenshot.png',color_mode='rgb',target_size=(256, 256),interpolation='nearest',keep_aspect_ratio=False)

Compressing PIL image without saving the file

I am having trouble with compressing image in python without saving the image at the disk. The image has a save function as described here. Here it optimizes the image by saving it. Is it possible to use the same procedure without saving the image. I want to do it like another python function.
image=image.quantize() [here it reduces the quality a lot ]
Thanks in advance :)
In PIL or opencv the image is just a large matrix with values for its pixels. If you want to do something with the image(e.g. display it), the function needs to know all the pixel values, and thus needs the extracted image.
However, there is a method to keep the image compressed in memory until you really need to do something with the image. Have a look at this answer: How can i load a image in Python, but keep it compressed?

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:
Below is the saved image:
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.
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.
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)
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
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.

Am I creating lossless PNG images?

I am doing image processing in a scientific context. Whenever I need to save an image to the hard drive, I want to be able to reopen it at a later time and get exactly the data that I had before saving it. I exclusively use the PNG format, having always been under the impression that it is a lossless format. Is this always correct, provided I am not using the wrong bit-depth? Should encoder and decoder play no role at all? Specifically, the images I save
are present as 2D numpy arrays
have integer values from 0 to 255
are encoded with the OpenCV imwrite() function, e.g. cv2.imwrite("image.png", array)
PNG is a lossless format by design:
Since PNG's compression is fully lossless--and since it supports up to 48-bit truecolor or 16-bit grayscale--saving, restoring and re-saving an image will not degrade its quality, unlike standard JPEG (even at its highest quality settings).
The encoder and decoder should not matter, in regards of reading the images correctly. (Assuming, of course, they're not buggy).
And unlike TIFF, the PNG specification leaves no room for implementors to pick and choose what features they'll support; the result is that a PNG image saved in one app is readable in any other PNG-supporting application.
While png is lossless, this does not mean it is uncompressed by default.
I specify compression using the IMWRITE_PNG_COMPRESSION flag. It varies between 0 (no compression) and 9 (maximum compression). So if you want uncompressed png:
cv2.imwrite(filename, data, [cv2.IMWRITE_PNG_COMPRESSION, 0])
The more you compress, the longer it takes to save.
Link to docs

Strange bug while combining images in Python

I have a hundred 10x10 px images, and I want to combine them into a big 100x100 image. I'm using the Image library to first create a blank image and then paste in the smaller images:
blank = Image.new('P',(100,100))
blank.paste(im,box)
The smaller images are in color, but the resulting image turns out in all grayscale. Is there a fix or workaround for this?
It's probably something to do with using a palette type image (mode P). Is there a specific reason you are doing this? If not, try passing 'RGB' as the first argument.

Categories