python mahotas.imread reads a 2d image as 3d - python

I have an image saved by another code of mine. The image is a normal JPG file. I saved it with imsave.
now when I'm reading it in another code, it seems to be 3d :S
the image is here.
and a simple code to read it is this :
import mahotas
img = mahotas.imread('d:/normal.jpg')
print img.shape, img.dtype

Try reading the jpg as greyscale like this:
mahotas.imread('d:/normal.jpg', as_grey = True)

(Author of mahotas here).
The suggestion by Junuxx is correct:
mahotas.imread('file.jpg', as_grey=True)
This reads the RGB file and converts it to grey scale by a weighted average of the components (they are not equally weighted, but use typical coefficients that attempt to be perceptually more accurate).
The alternative (which I rather prefer) is:
im = mahotas.imread('file.jpg')
im = im[:,:,0]
I assume that all the channels have the same values and just use the first one.

Related

Displaying Tiff images in ipynb or jupyter notebook

I am trying to visualize a tiff image in an ipython notebook using the following code, import statements are ignored for clarity purposes.
from PIL import Image
orig_img_path = os.path.join("path/to/tiff/0.tiff")
img_orig = Image.open(orig_img_path,"r")
plt.imshow(img_orig)
plt.show()
The above snippet just shows me the following black image -
I know that the image pixel values are non-zero since I can open the original images on my MacBook and they look like the following -
I also double check that the pixel values are nonzero by using the following code of casting the PIL image to an np array using the following code and printing the array out -
img_arr = np.array(img_orig)
print(img_arr)
which gives me the following output -
I think I know what the issue is as well - that the matplotlib pyplot thinks that this is a PNG image or something like that and as we can see the pixel values are very small to be perceivable by the human eyes. I mean I can simply multiply the image by 255 which gives the following image as expected, although scaling by 255 is not entirely right since the pixel values need to be normalized for the minimum to corrspond to 0 and max to 255 assuming mat plot lib thinks that it is showing a PNG image -
I would like to know if there is a better way of doing so rather than me manually doing it all the time, any native way of displaying tiff in a Jupyter/ipython notebook which preserves all the good properties of tiff images such as floating point numbers etc.
Thanks and please let me know if anything is unclear.
Edit 1: Link to the original file is here - https://drive.google.com/file/d/1O1-QM6aeU5-QZhT36vOMjDND2vkZNgqB/view?usp=sharing
-- Megh
If you share your original image in .tiff format the solution might be more precise.
You are reading the image pixels as type float: 0-1, and after that, you parse them as uint8 : 0-255 which will turn all pixels values into 0 or 1: Black or almost Black
You can try the following approach to read your image (supposedly Black and White) and parse it:
import cv2
gray = cv2.imread("path/to/tiff/0.tiff", cv2.IMREAD_UNCHANGED)
cv2.namedWindow("MyImage", cv2.WINDOW_NORMAL)
cv2.imshow("MyImage", gray)
cv2.waitKey(0)
What is the range of values that you expect in that image? Did you do any preprocessing to it?
The image you are trying to display in matplotlib contains negative values. Visualizing works well for any kind of uint8 data (Grayscale and RGB) and data in the range of 0 - 1. Your displaying issue can be addressed by adding the min value of the image and then dividing by the max value (effectively normalizing your data to the range 0-1).
[...]
img = np.array(img_orig, dtype=float)
img += abs(np.min(img))
img /= np.max(img)
plt.imshow(img)
plt.show()

How to convert a float32 img to uint8 where range is(-1 to -0.85)?

I want to convert a float32 image into uint8 image in Python.
I tried using the following code, but the output image only has values like 2 and 3 so the image is practically black.
gen_samples[0] * 255).round().astype(np.uint8)
When I try displaying the float32 image I get a blackish/greyish image where I can somewhat make out the required image.
Normalize the array to 0..1 first.
Assuming gen_samples is the image matrix:
arr_min = np.min(gen_samples)
arr_max = np.max(gen_samples)
gen_samples = (gen_samples - arr_min) / (arr_max - arr_min)
Since you tagged the question using scikit-image you are probably using skimage. In this case img_as_ubyte should do the trick:
from skimage.util import image_as_ubyte
img = img_as_ubyte(gen_samples[0])
Further, since you tagged the question with imageio-python I'll assume that the image data actually comes from some (binary) image format rather than being generated in the script. In this case, you can often use the backend that does the decoding and do the conversion while the image is being loaded. This is, however, specific to the format being used, so for a more specific answer you would have to provide more insight into where your images are coming from.

Python PIL read/open TIFF is black only

I try to read a TIFF file with pillow/PIL (7.2.0) in Python (3.8.3), e.g. this image.
The resulting file seems to be corrupted:
from PIL import Image
import numpy as np
myimage = Image.open('moon.tif')
myimage.mode
# 'L'
myimage.format
# 'TIFF'
myimage.size
# (358, 537)
# so far all good, but:
np.array(myimage)
# shows only zeros in the array, likewise
np.array(myimage).sum()
# 0
It doesn't seem to be a problem of the conversion to numpy array only, since if I save it to a jpg (myimage.save('moon.jpg')) the resulting jpg image has the appropriate dimensions but is all black, too.
Where did I do wrong or is it a bug?
I am not an expert in coding but i had same problem and found the TIFF file has 4 layers. R, G ,B and Alpha. When you convert it using PIL it is black.
try to view the image as plt.imshow(myimage[:, :, 0])
you could also remove the Alpha layer by saving the read image ( i used plt.imread('image')) and then saving it as image=image[:,:,3]. Now its a RGB image.
I don't know if i answered your question, but i felt this info might be of help.

convert greyscale image back to vector

I have a list called w (size: 784), which I outputted to a png greyscale image:
import matplotlib.pyplot as plt
tmp = 1/(1+np.exp(-10*w/w.max()))
plt.imshow(tmp.reshape(28,28),cmap="gray")
plt.draw()
plt.savefig("final_weight_vector")
Now I want to read the png image back to be a vector.
The solutions I found so far:
First:
import matplotlib.image as mpimg
img=mpimg.imread('final_weight_vector.png')
but img appears to not be greyscale, because its dimensions turend out to be (600, 800, 4).
Second:
reading the file as RGB and converting to greyscale:
im = Image.open('final_weight_vector.png').convert('LA')
However, I couldn't find how to iterate over im so I have no idea as to what's inside. Further, I am not sure the output of im will have the exact same values as the original w.
Help please?
The problem is that what you saved is probably a plot of the 28x28 image, not the image itself.
To be sure, please preview the image. I bet it is 600x800, not 28x28. I also suppose it contains many additional elements, like axes and padding.
If you want to store your array in a loadable format, you may use numpy.save() (and numpy.load() to load it).
You may also use PIL to save your array as image (e.g. using something similar to: http://code.activestate.com/recipes/577591-conversion-of-pil-image-and-numpy-array/)

From Raw binary image data to PNG in Python

After searching for a few hours, I ended up on this link. A little background information follows.
I'm capturing live frames of a running embedded device via a hardware debugger. The captured frames are stored as raw binary files, without headers or format. After looking at the above link and understanding, albeit perfunctorily, the NumPY and Matplotlib, I was able to convert the raw binary data to an image successfully. This is important because I'm not sure if the link to the raw binary file will help any one.
I use this code:
import matplotlib.pyplot as plt # study documentation
import numpy as np # " "
iFile = "FramebufferL0_0.bin" # Layer-A
shape = (430, 430) # length and width of the image
dtype = np.dtype('<u2') # unsigned 16 bit little-endian.
oFile = "FramebufferL0_0.png"
fid = open(iFile, 'rb')
data = np.fromfile(fid, dtype)
image = data.reshape(shape)
plt.imshow(image, cmap = "gray")
plt.savefig(oFile)
plt.show()
Now, the image I'm showing is black and white because the color map is gray-scale (right?). The actual captured frame is NOT black and white. That is, the image I see on my embedded device is "colorful".
My question is, how can I calculate actual color of each pixel from the raw binary file? Is there a way I can get the actual color map of the image from the raw binary? I looked into this example and I'm sure that, if I'm able to calculate the R, G and B channels (and Alpha too), I'll be able to recreate the exact image. An example code would be of much help.
An RGBA image has 4 channels, one for each color and one for the alpha value. The binary file seems to have a single channel, as you don't report an error when performing the data.reshape(shape) operation (the shape for the corresponding RGBA image would be (430, 430, 4)).
I see two potential reasons:
The image actual does have colour information but when you are grabbing the data you are only grabbing one of the four channels.
The image is actually a gray-scale image, but the embedded device shows a pseudocolor image, creating the illusion of colour information. Without knowing what the colourmap is being used, it is hard to help you, other than point you towards matplotlib.pyplot.colormaps(), which lists all already available colour maps in matplotlib.
Could you
a) explain the exact source / type of imaging modality, and
b) show a photo of the output of the embedded device?
PS: Also, at least in my hands, the pasted binary file seems to have a size of 122629, which is incongruent with an image shape of (430,430).

Categories