Why are these two arrays exactly the same? - python

This is my code.
import sys, os
import numpy as np
import matplotlib.pyplot as plt
import PIL
from PIL import Image
im = Image.open('C:/research/1.jpg')
im_bicubic = Image.open('C:/research/1.jpg')
wei, hei = im.width, im.height
im = im.resize((wei,hei), 0)
im_bicubic = im_bicubic.resize((wei,hei), PIL.Image.BICUBIC)
im.save('C:/research/1ori.jpg')
im_bicubic.save('C:/research/1bic.jpg')
Original image saved to "im".
bicubic interpolated image has been saved to "im_bicubic".
And I saved it to any folder, but when I look at it, there is no difference between the two images.
I added this code for verification.
im_array=np.asarray(im)
im_bicubic_array=np.asarray(im_bicubic)
print(im_bicubic_array - im_array)
The result is an array with all zeros.
The two arrays are exactly the same.
Why is one the original and the one using the interpolation method the same?
pillow, bicubic, I used another, but it was the same too.
Why are the two images exactly the same?
Did I mistake the code so that bicubic did not work?
Thanks you.

Since you are resizing to exactly the same shape, there is no need to interpolate. This is why both images are still the same.
Interpolation does only make sense, if you are resizing to another shape.

Related

How can I obtain all 2D slices from a 3D image at once?

I'm using the following code to slice a 3D image:
import nibabel as nib
import numpy as np
from nibabel.testing import data_path
import os
vol1= np.load("teste01.npy")
zSlice= (vol1[200, :, :]).squeeze()
print (zSlice.shape)
np.save("D:/Volumes convertidos LIDC/slice200.npy", zSlice)
The problem is that I need to do it manually, I need to obtain all slices and there are just to many for it to be possible to keep doing it like that. Is there any alternative?
If I understand correctly what you want to do, the following should work:
for i, s in enumerate(vol1):
np.save(f"D:/Volumes convertidos LIDC/slice{i}.npy", s)
This will save each 2-dimensional slice taken along the 0-th axis in a separate file (which can mean a lot of files)

I have text file with a 2D matrix in it. How do turn this into a grey scale image in python?

I'm fairly new with python so I'm not really sure where to start. All I have done is I imported the text file to python. I was suggested to use matshow.py but I don't know how I would use the text file to create the actual image.
If you can contrive to get your text file into a numpy array then this kind of code will work. Just research, or ask another question, about reading a text file into a numpy array.
>>> from PIL import Image
>>> import numpy as np
>>> pic = np.zeros((100,100), dtype=np.int8)
>>> image = Image.fromarray(pic)
>>> image.show()
Here I import the Image class from the PIL library. Then I create a 100x100 array of zeroes in pic using numpy. I use a method from Image to make this into an Image object and then display the (utterly uninteresting, completely black) result.
What exactly are you trying to achieve, your point isn't clear.
if you are trying to draw an image using a matrix.
you will need to look into PIL.
Here is the link to download the library and here is the link for the documentations.
Try
Matrix = loadtxt(filename)
imshow(Matrix)
These functions come from the numpy and matplotlib libraries, respectivelly.

how to read in png into n x n-array with predefined value of "n" in matplotlib using imread

The following reads in a png into an array:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img=mpimg.imread('example.png')
the result is the array img, which is e.g. a 1024 x 1024-array of tuples (see http://matplotlib.org/1.3.1/users/image_tutorial.html):
How I can enforce, that my result is an n x n-array (of tuples) instead of the 1024 x 1024-array (n<1024)? I need to explicitly define the dimension of that array (e.g. set 400x400).
Thanks in advance
I recommend installing pillow (preferably using Anaconda). It makes image manipulation easy — mostly easier than treating the image as a raw ndarray.
Once you have pillow installed, this answer should help: How do I resize an image using PIL and maintain its aspect ratio?
If you really want to keep it as an array, then you could use scipy.misc.imresize.
Edit to add the thing that actually worked, in case others miss it:
import scipy.misc
img_rescaled = scipy.misc.imresize(img, size=[400,400], interp='bilinear')

Python OpenCV drawing errors after manipulating array with numpy

I'm reading in an image with OpenCV, and trying to do something with it in numpy (rotate 90deg). Viewing the result with imshow from matplotlib, it all seems to be working just fine - image is rotated. I can't use drawing methods from OpenCV on the new image, however. In the following code (I'm running this in a sagemath cloud worksheet):
%python
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, sys
image = np.array( cv2.imread('imagename.png') )
plt.imshow(image,cmap='gray')
image = np.array(np.rot90(image,3) ) # put it right side up
plt.imshow(image,cmap='gray')
cv2.rectangle(image,(0,0),(100,100),(255,0,0),2)
plt.imshow(image,cmap='gray')
I get the following error on the cv2.rectangle() command:
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
The error goes away if I use np.array(np.rot90(image,4) ) instead (i.e. rotate it 360). So it appears that the change in dimensions is messing it up. Does OpenCV store the dimensions somewhere internally that I need to update or something?
EDIT: Adding image = image.copy() after rot90() solved the problem. See rayryeng's answer below.
This is apparently a bug in the Python OpenCV wrapper. If you look at this question here: np.rot90() corrupts an opencv image, apparently doing a rotation that doesn't result back in the original dimensions corrupts the image and the OP in that post experiences the same error you are having. FWIW, I also experienced the same bug.... no idea why.
A way around this is to make a copy of the image after you rotate, and then show the image. This I can't really explain, but it seems to work. Also, make sure you call plt.show() at the end of your code to show the image:
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, sys
image = np.array( cv2.imread('imagename.png') )
plt.imshow(image,cmap='gray')
image = np.array(np.rot90(image,3) ) # put it right side up
image = image.copy() # Change
plt.imshow(image,cmap='gray')
cv2.rectangle(image,(0,0),(100,100),(255,0,0),2)
plt.imshow(image,cmap='gray')
plt.show() # Show image
I faced the same problem with numpy 1.11.2 and opencv 3.3.0. Not sure why, but this did the job for me.
Before using cv2.rectangle, add the line below:
image1 = image1.transpose((1,0)).astype(np.uint8).copy()
Reference
Convert data type works for my problem.
The image is of type np.int64 before the convert.
image = image.astype(np.int32) # convert data type

Scale imread matrix in python

I am looking for a way to rescale the matrix given by reading in a png file using the matplotlib routine imread,
e.g.
from pylab import imread, imshow, gray, mean
from matplotlib.pyplot import show
a = imread('spiral.png')
#generates a RGB image, so do
show()
but actually I want to manually specify the dimension of $a$, say 200x200 entries, so I need some magic command (which I assume exists but cannot be found by myself) to interpolate the matrix.
Thanks for any useful comments : )
Cheers
You could try using the PIL (Image) module instead, together with numpy. Open and resize the image using Image then convert to array using numpy. Then display the image using pylab.
import pylab as pl
import numpy as np
from PIL import Image
path = r'\path\to\image\file.jpg'
img = Image.open(path)
img.resize((200,200))
a = np.asarray(img)
pl.imshow(a)
pl.show()
Hope this helps.

Categories

Resources