Resample image rasterio/gdal, Python - python

How can I resample a single band GeoTIFF using Bilinear interpolation?
import os
import rasterio
from rasterio.enums import Resampling
from rasterio.plot import show,show_hist
import numpy as np
if __name__ == "__main__":
input_Dir = 'sample.tif'
#src = rasterio.open(input_Dir)
#show(src,cmap="magma")
upscale_factor = 2
with rasterio.open(input_Dir) as dataset:
# resample data to target shape
data = dataset.read(
out_shape=(
dataset.count,
int(dataset.height * upscale_factor),
int(dataset.width * upscale_factor)
),
resampling=Resampling.bilinear
)
# scale image transform
transform = dataset.transform * dataset.transform.scale(
(dataset.width / data.shape[-1]),
(dataset.height / data.shape[-2])
)
show(dataset,cmap="magma",transform=transform)
I have tried the following code and my output is as follows:
I am trying to achieve the following output:

One option would be to use the GDAL python bindings. Then you can perform the resample in memory (or you can save the image if you want). Assuming the old raster resolution was 0.25x0.25 and you're resampling to 0.10x0.10:
from osgeo import gdal
input_Dir = 'sample.tif'
ds = gdal.Translate('', input_Dir, xres=0.1, yres=0.1, resampleAlg="bilinear", format='vrt')
If you want to save the image put output filepath instead of the empty string for the first argument and change the format to 'tif'!

Related

how to compare an image with a folder of images ( then do a certain thing when they are 50% alike or something )

so i was wondering if there was sth like
pyautogui.locateOnScreen('picuture.jpg',confidence=x)
I'm currently trying to compare pictures from a folder, but pyautogui only works with "onScreen" images. I don't want to check if the picture are 1:1 the same, but if they are alike, with pyautogui you can simply add the "confidence" parameter and i've built my script based on that i just wanted to know if someone knows a way to do that.
This code checks if there are any duplicates in a folder its a bit slow though.
import image_similarity_measures
from image_similarity_measures.quality_metrics import rmse, psnr
from sewar.full_ref import rmse, psnr
import cv2
import os
import time
def check(path_orginal,path_new):#give r strings
original = cv2.imread(path_orginal)
new = cv2.imread(path_new)
return rmse(original, new)
def folder_check(folder_path):
i=0
file_list = os.listdir(folder_path)
print(file_list)
duplicate_dict={}
for file in file_list:
# print(file)
file_path=os.path.join(folder_path,file)
for file_compare in file_list:
print(i)
i+=1
file_compare_path=os.path.join(folder_path,file_compare)
if file_compare!=file:
similarity_score=check(file_path,file_compare_path)
# print(str(similarity_score))
if similarity_score==0.0:
print(file,file_compare)
duplicate_dict[file]=file_compare
file_list.remove(str(file))
return duplicate_dict
start_time=time.time()
print(folder_check(r"C:\Users\Admin\Linear-Regression-1\image-similarity-measures\input1"))
end_time=time.time()
stamp=end_time-start_time
print(stamp)
You can use numpy to compare the pixel array of two images.
from PIL import Image
import numpy as np
# import the image as pixels
img_a = Image.open('a.jpg')
img_b = Image.open('b.jpg')
img_a_pixels = img_a.load()
img_b_pixels = img_b.load()
# transform them into numpy array
img_a_array = np.array(img_a_pixels)
img_b_array = np.array(img_b_pixels)
# compare the difference
difference = (img_a_array == img_b_array).sum()
Then you can see if the difference exceeds your threshold. If it does not , you can consider them similar.

Python "make_transforms" shows list index error while aligning fits images

I am trying to align 4 fits (V2.fits,V3.fits,V4.fits and, V5.fits) with respect to a reference fits file (V1.fits). I tried the following by employing the python fits_align package :
from fits_align.ident import make_transforms
from fits_align.align import affineremap
from glob import glob
from astropy.io import fits
from numpy import shape
import os
img_list = sorted(glob(os.path.join("*.fits")))
ref_image = img_list[0]
images_to_align = img_list[1:]
print(img_list) # List of all images
print(ref_image) # Reference image
print(images_to_align) # Images to align
identifications = make_transforms(ref_image, images_to_align)
aligned_images = [ref_image]
for id in identifications:
if id.ok:
alignedimg = affineremap(id.ukn.filepath, id.trans, outdir=tmpdir)
aligned_images.append(alignedimg)
I get the following index error:
What could be the reasons for this error? please suggest possible solutions

Cut NetCDF files by shapefile

I have a large dataset of global .nc files and I am trying to clip them to a smaller area. I have this area stored as a .shp file.
I have tried using gdal from Qgis but needs to do this by converting each variable and I must select each variable and same shape for all files one by one and with 400 files going trough each variable seems not the best idea. Also this returns .tiff files separated and not the .nc file that i am aiming for.
I had this little script but its not doing what i need
import glob
import subprocess
import os
ImageList = sorted(glob.glob('*.nc'))
print('number of images to process: ', len(ImageList))
Shapefile = 'NHAF-250m.shp'
# Create output directory
OutDir = './Clipped_Rasters/'
if not os.path.exists(OutDir):
os.makedirs(OutDir)
for Image in ImageList:
print('Processing ' + Image)
OutImage = OutDir + Image.replace('.nc', '_BurnedArea_Clipped.tif') # Defines Output Image
# Clip image
subprocess.call('gdalwarp -q -cutline /Users/path/to/file/NHAF-250-vector/ -tr 0.25 0.25 -of GTiff NETCDF:'+Image+":burned_area "+OutImage, shell=True)
print('Done.' + '\n')
print('All images processed.')
Thank you in advance
I recommend to use xarray to handle netcdf data and geopandas + rasterio to handle your Shapefile.
import geopandas
import xarray
import rasterio
import glob
shapefile = 'NHAF-250m.shp'
sf = geopandas.read_file(shapefile)
shape_mask = rasterio.features.geometry_mask(sf.iloc[0],
out_shape=(len(ndvi.y), len(ndvi.x)),
transform=ndvi.geobox.transform,
invert=True)
shape_mask = xarray.DataArray(shape_masj , dims=("y", "x"))
file_list = sorted(glob.glob('*.nc'))
for file in file_list:
nc_file = xarray.open_dataset(file)
# Then apply the mask
masked_netcdf_file = nc_file.where(shape_mask == True, drop=True)
# store again as netcdf or do what every you want with the masked array

how to load images into a python list and convert to a dataframe object

I am trying to read a bunch of png images in a directory into a python list. After getting the images in the list I would like to resize and do some reshaping. But it always throws an error. Below is the sample of my code.
Well it doesn't really throw an error but it always prints out an empty dataset.
import pandas as pd
from sklearn.manifold import Isomap
from scipy import misc
from os import listdir
import glob
dset = []
for image_path in glob.glob("/Documents/Python/DAT210x-master/Module4 /Datasets/ALOI/32/*.png"):
img = misc.imread(image_path)
img = img[::2, ::2]
X = (img / 255.0).reshape(-1)
dset.append(X)
dset = pd.DataFrame(dset)
print(dset)
If I'm not mistaken, DataFrame objects are typically initialized from dict objects. What happens if you add:
dset = {'Pictures': dset}
dset = pd.DataFrame(dset)

Importing images for manifold Isomap

There are 192 x 144 pixel images. They should be imported to a Python list so that the items in the list are NDArray instances. New dataframe should be created from the list and that dataframe should be given to Isomap. iso.fit(df) fails with the errors
array = array.astype(np.float64)
ValueError: setting an array element with a sequence.
I have spent more than one day trying to figure out how the NDArrays should be processed and the dataframe loaded with them. No luck. Any help would be appreciated.
import pandas as pd
from scipy import misc
import glob
from sklearn import manifold
samples = []
for filename in glob.glob('Datasets/ALOI/32/*.png'):
img = misc.imread(filename, mode='I')
samples.append(img)
df = pd.DataFrame.from_records(samples, coerce_float=True)
iso = manifold.Isomap(n_neighbors=6, n_components=3)
iso.fit(df)
If those are gray scale images from the ALOI, you probably want to treat each pixel's brightness as a feature. Therefore, you should flatten the img array with img.reshape(-1). The revised code follows:
import pandas as pd
from scipy import misc
import glob
from sklearn import manifold
samples = []
for filename in glob.glob('Datasets/ALOI/32/*.png'):
img = misc.imread(filename, mode='I')
# the following line changed
samples.append(img.reshape(-1))
df = pd.DataFrame.from_records(samples, coerce_float=True)
iso = manifold.Isomap(n_neighbors=6, n_components=3)
iso.fit(df)

Categories

Resources