A remote sensing image is usually relatively large, so how to crop or cut the remote sensing image through code?
After the corresponding processing, it is necessary to stitch and merge the cut images, what should I do?
Ever since I came into contact with remote sensing images, I found that the gdal library is easy to use!
Mom no longer has to worry that I can't process remote sensing images!
so easy!!!
Today, I will introduce how gdal, the protagonist, realizes cutting and merging of remote sensing images.
Without further ado, go directly to the code!
from osgeo import osr, gdal
import numpy as np
import os
from PIL import Image
import time
from skimage import io
import gdal
def get_file_names(data_dir, file_type = ['tif','tiff']):
result_dir = []
result_name = []
for maindir, subdir, file_name_list in os.walk(data_dir):
for filename in file_name_list:
apath = maindir+'/'+filename
ext = apath.split('.')[-1]
if ext in file_type:
result_dir.append(apath)
result_name.append(filename)
else:
pass
return result_dir, result_name
def get_same_img(img_dir, img_name):
result = {}
for idx, name in enumerate(img_name):
temp_name = ''
for idx2, item in enumerate(name.split('_')[:-4]):
if idx2==0:
temp_name = temp_name+item
else:
temp_name = temp_name+'_'+item
if temp_name in result:
result[temp_name].append(img_dir[idx])
else:
result[temp_name] = []
result[temp_name].append(img_dir[idx])
return result
def assign_spatial_reference_byfile(src_path, dst_path):
src_ds = gdal.Open(src_path, gdal.GA_ReadOnly)
sr = osr.SpatialReference()
sr.ImportFromWkt(src_ds.GetProjectionRef())
geoTransform = src_ds.GetGeoTransform()
dst_ds = gdal.Open(dst_path, gdal.GA_Update)
dst_ds.SetProjection(sr.ExportToWkt())
dst_ds.SetGeoTransform(geoTransform)
dst_ds = None
src_ds = None
def cut(in_dir, out_dir, file_type = ['tif','tiff'], out_type = 'png',out_size = 1024):
if not os.path.exists(out_dir):
os.makedirs(out_dir)
data_dir_list,_ = get_file_names(in_dir, file_type)
count = 0
print('Cut begining for ', str(len(data_dir_list)), ' images.....' )
for each_dir in data_dir_list:
time_start = time.time()
#image = np.array(io.imread(each_dir))
image = np.array(Image.open(each_dir))
print(image.shape)
cut_factor_row = int(np.ceil(image.shape[0]/out_size))
cut_factor_clo = int(np.ceil(image.shape[1]/out_size))
for i in range(cut_factor_row):
for j in range(cut_factor_clo):
if i == cut_factor_row-1:
i = image.shape[0]/out_size-1
else:
pass
if j== cut_factor_clo-1:
j = image.shape[1]/out_size-1
else:
pass
start_x = int(np.rint(i*out_size))
start_y = int(np.rint(j*out_size))
end_x = int(np.rint((i+1)*out_size))
end_y = int(np.rint((j+1)*out_size))
temp_image = image[start_x:end_x,start_y:end_y,:]
print('temp_image:',temp_image.shape)
out_dir_images = out_dir+'/'+each_dir.split('/')[-1].split('.')[0] \
+'_'+str(start_x)+'_'+str(end_x)+'_'+str(start_y)+'_'+str(end_y)+'.'+out_type
out_image = Image.fromarray(temp_image)
out_image.save(out_dir_images)
src_path = 'F:/带地理坐标.tif' #带地理影像
assign_spatial_reference_byfile(src_path, out_dir_images)
count += 1
print('End of '+str(count)+'/'+str(len(data_dir_list))+'...')
time_end = time.time()
print('Time cost: ', time_end-time_start)
print('Cut Finsh!')
return 0
def combine(data_dir, w, h, c, out_dir, out_type='tif', file_type=['tif', 'tiff']):
if not os.path.exists(out_dir):
os.makedirs(out_dir)
img_dir, img_name = get_file_names(data_dir, file_type)
print('Combine begining for ', str(len(img_dir)), ' images.....' )
dir_dict = get_same_img(img_dir, img_name)
count = 0
for key in dir_dict.keys():
temp_label = np.zeros(shape=(w,h,c),dtype=np.uint8)
dir_list = dir_dict[key]
for item in dir_list:
name_split = item.split('_')
x_start = int(name_split[-4])
x_end = int(name_split[-3])
y_start = int(name_split[-2])
y_end = int(name_split[-1].split('.')[0])
img = Image.open(item)
img = np.array(img)
temp_label[x_start:x_end,y_start:y_end,:]=img
img_name=key+'.'+out_type
new_out_dir=out_dir+'/'+img_name
label=Image.fromarray(temp_label)
label.save(new_out_dir)
src_path = 'F:/带地理坐标.tif' #带地理坐标影像
assign_spatial_reference_byfile(src_path, new_out_dir)
count+=1
print('End of '+str(count)+'/'+str(len(dir_dict))+'...')
print('Combine Finsh!')
return 0
if __name__=='__main__':
##### cut
data_dir='F:/Level1'
out_dir='F:/Level1/cut_960'
file_type=['tif']
out_type='tif'
cut_size=960
cut(data_dir,out_dir,file_type,out_type,cut_size)
##### combine
# data_dir='F:/Level1/cut_960'
# h=3072
# w=1792
# c=3
# out_dir='F:/Level1'
# out_type='tif'
# file_type=['tif']
#
# combine(data_dir, w, h, c, out_dir, out_type, file_type)
Among them: cut function is the cutting function; combine is the splicing function
Instructions for use of the cut function
data_dir: store the image folder to be cropped , no need to assign to tif file
out_dir: the image folder where the cropping results are stored
file_type: The type of image file to be cropped, not necessarily tif, I have a lot of tif files, so I take them all as tif
out_type: The image file type of the cropping result, not necessarily tif, depending on your needs
cut_size: cut size, cut to n*n square
Instructions for using the combine function
data_dir: store the image folder to be cropped , no need to assign to tif file
w, h, c: width, height and number of bands of the stitched image
out_dir: the image folder where the cropping results are stored
out_type: The image file type of the cropping result, not necessarily tif, depending on your needs
file_type: The type of image file to be cropped, not necessarily tif, I have a lot of tif files, so I take them all as tif
Note: The assign_spatial_reference_byfile function adds geographic coordinates to the image data. If the image you want to splice itself has geographic coordinates, then you can comment out this function and the place of this function. Moreover, the tif file of src_path in the assign_spatial_reference_byfile function in the code is an image with geographic coordinates, otherwise an error will be reported!
If you have any questions, you can leave a message, and I will help you debug!