Plotting two images side by side in python - python

I'd like to plot two images side by side in Python using matplotlib. However I don't want to create separate subplots. I want to plot two images in the same figure so that I can draw correspondences between the two images. See image below.
In Matlab I believe this can be done using imshow([I1, I2]) however the python API for matplotlib does not accept an array of images. Is there a way to do this in python?

If you use numpy you can simply make one large array that represents the two images using the numpy concatenate function:
import numpy as np
import matplotlib.pyplot as plt
img_A = np.ones((10,10))
img_B = np.ones((10,10))
plot_image = np.concatenate((img_A, img_B), axis=1)
plt.imshow(plot_image)
plt.show()

Related

How can I cut a portion of a satellite image based on coordinates? (gdal)

I have a satellite image of 7-channels (Basically I have seven .tif files, one for each band). And I have a .csv file with coordinates of points-of-interest that are in the region shot by the satellite. I want to cut small portions of the image in the surroundings of each coordinate point. How could I do that?
As I don't have a full working code right now, it really doesn't matter the size of those small portions of image. For the explanation of this question let's say that I want them to be 15x15 pixels. So for the moment, my final objective is to obtain a lot of 15x15x7 vectors, one for every coordinate point that I have in the .csv file. And that is what I am stucked with. (the "7" in the "15x15x7" is because the image has 7 channels)
Just to give some background in case it's relevant: I will use those vectors later to train a CNN model in keras.
This is what I did so far: (I am using jupyter notebook, anaconda environment)
imported gdal, numpy, matplotlib, geopandas, among other libraries.
Opened the .gif files using gdal, converted them into arrays
Opened the .csv file using pandas.
Created a numpy array called "imagen" of shape (7931, 7901, 3) that will host the 7 bands of the satellite image (in form of numbers). At this point I just need to know which rows and colums of the array "imagen" correspond to each coordinate point. In other words I need to convert every coordinate point into a pair of numbers (row,colum). And that is what I am stucked with.
After that, I think that the "cutting part" will be easy.
#I import libraries
from osgeo import gdal_array
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import geopandas
from geopandas import GeoDataFrame
from shapely.geometry import Point
#I access the satellite images (I just show one here to make it short)
b1 = r"E:\Imágenes Satelitales\2017\226_86\1\LC08_L1TP_226086_20170116_20170311_01_T1_sr_band1.tif"
band1 = gdal.Open(b1, gdal.GA_ReadOnly)
#I open the .csv file
file_svc = "C:\\Users\\Administrador\Desktop\DeepLearningInternship\Crop Yield Prediction\Crop Type Classification model - CNN\First\T28_Pringles4.csv"
df = pd.read_csv(file_svc)
print(df.head())
That prints something like this:
Lat1 Long1 CropingState
-37.75737 -61.14537 Barbecho
-37.78152 -61.15872 Verdeo invierno
-37.78248 -61.17755 Barbecho
-37.78018 -61.17357 Campo natural
-37.78850 -61.18501 Campo natural
#I create the array "imagen" (I only show one channel here to make it short)
imagen = (np.zeros(7931*7901*7, dtype = np.float32)).reshape(7931,7901,7)
imagen[:,:,0] = band1.ReadAsArray().astype(np.float32)
#And then I can plot it:
plt.imshow(imagen[:,:,0], cmap = 'hot')
plt.plot()
Which plots something like this:
(https://github.com/jamesluc007/DeepLearningInternship/blob/master/Crop%20Yield%20Prediction/Crop%20Type%20Classification%20model%20-%20CNN/First/red_band.png)
I want to transform those (-37,-61) into something like (2230,1750). But I haven't figured it how yet. Any clues?

Why are these two arrays exactly the same?

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.

Obtaining z-buffer(depth) informaiton from dicom file in python

I have a set of dicom images(contains 160 .dcm files). I can visualize a single file by the following python code:
import pydicom as dicom
import os
import numpy
import matplotlib.pyplot as plt
filename = "./myfiles/MR000130.dcm";
dataset = dicom.dcmread(filename)
plt.imshow(dataset.pixel_array, cmap=plt.cm.bone)
plt.show()
My question is:
How do I visualize these whole bunch of volumetric data as a single picture?
Is there any way to obtain the z-buffer information?
It's in the file. There is stuff in the DICOM apart from pixel data. See it with
print(dataset._pretty_str).
It might be dataset.SliceLocation.
We can't tell you how to change 3D to 2D. You could read all the slices, and then reslice in other planes. You could do some fancy segmentation and render surfaces in 3D. You need to decide what is most appropriate for your case.

Concatenated images are badly degraded

I am trying to display several pictures on my Jupyter notebook. However, the pixel is really rough like below.
The pixel of original picture is clear. How should I improve this issue ?
This is a certain point of process to have a classification whether the picture is dog or cat. I have a many pictures of dogs and cat in the folder located on same directory and just took them from there. The picture is I just tried to show on the Jupyter notebook with using matplotlib.
Thank you in advance.
To force the resolution of the matplotlib inline images:
import matplotlib as plt
dpi = 300 # Recommended to set between 150-300 for quality image preview
plt.rcParams['figure.dpi'] = dpi
I think it uses a very low setting around 80 dpi by default.
The image quality seems to be degraded in the example picture simply because you are trying to show a 64 pixel large image on 400 pixels or so on screen. Each original pixel thus comprises several pixels on screen.
It seems you do not necessarily want to use matplotlib at all if the aim is to simply show the image in its original size on screen.
%matplotlib inline
import numpy as np
from IPython import display
from PIL import Image
a = np.random.rand(64,64,3)
b = np.random.rand(64,64,3)
c = (np.concatenate((a,b), axis=1)*255).astype(np.uint8)
display.display(Image.fromarray(c))
To achieve a similar result with matplotlib, you need to crop the margin around the axes and make sure the figure size is exactly the size of the array to show.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
a = np.random.rand(64,64,3)
b = np.random.rand(64,64,3)
c = np.concatenate((a,b), axis=1)
fig, ax = plt.subplots(figsize=(c.shape[1]/100.,c.shape[0]/100.), dpi=100)
fig.subplots_adjust(0,0,1,1)
ax.axis("off")
_ = ax.imshow(c)

how to convert ndarray to image and display it using python

I have converted set of images to ndarray and stored it, now i have to convert them back to images without saving it to disk. I tried with " toimage() " function, but it is displaying only 1 image.
toimage(resizedlist.values()[0]).show()
resizedlist.values contains the ndarray of 49 images. Is there any way to display images randomly??
Thanks in advance!
To plot an ndarray as an image you can use matplotlib:
import numpy as np
import matplotlib.pyplot as plt
random = np.random.normal(0,1,size=[100,100])
plt.imshow(random,aspect="auto")
plt.show()
If your image data is stored RGBA, imshow will plot the image with the correct colours etc.
For reference, all this information can be found here:
http://matplotlib.org/1.3.1/users/image_tutorial.html

Categories

Resources