已有数据:1张大范围的遥感影像和1张裁剪为同一大小的shp数据
使用工具:ArcPy
实现目标:
1.shp数据按照属性分块输出
2.使用shp数据批量裁剪遥感影像,将影像裁剪为小块的tif图像
3.将tif转为jpg,并调整为同一大小
使用shp裁剪完的tif图像由原来的8位变为16位,直接打开是黑色的,转为jpg也是黑色,后续读取、处理图片都受影响。
查了如何将16位转为8位的代码,都没有解决问题,最终发现arcgis工具中有一个“复制栅格”可以实现将16位的栅格图像输出为8位栅格图像,查找官方文档,使用 arcpy.CopyRaster_management
函数,在参数中设置输出的像素深度为 "8_BIT_UNSIGNED"
即可实现这一功能。(在这里也遇到了一个坑,使用arcpy.CopyRaster_management
函数时,显示arcgisscripting.ExecuteError: ERROR 999999: 执行函数时出错。 尚未配置栅格存储。
将相对路径改为完整路径即可)
import arcpy
import io
import pandas as pd
import numpy as np
import cv2
import re
from arcpy import env
from arcpy.sa import *
from skimage import io
import os
import numpy as np
from PIL import Image
import glob
import tifffile as tif
'''
数据分割
'''
# function for replace special characters
def validateTitle(title):
rstr = r"[\/\\\:\*\?\"\<\>\|\,\.\ ]"
new_title = re.sub(rstr, "_", title)
return new_title
env.workspace = 'D:/test/split'
in_features = "D:/test/split/shp/clippart3.shp" #要分块的shp
rows = arcpy.SearchCursor(in_features, fields="labelnum") # 属性字段
for row in rows:
selected_field_value = row.getValue("labelnum")
where_clause = '"labelnum" = \'%s\''%(str(selected_field_value))
outfilename = validateTitle(str(selected_field_value))
out_feature_class = "D:/test/split/single/%s.shp"%(outfilename)#输出路径
arcpy.Select_analysis(in_features, out_feature_class, where_clause)
print(str(selected_field_value)+' has done!!!')
'''
用shp批量裁剪tif
'''
arcpy.CheckOutExtension("Spatial")
arcpy.env.workspace = "D:/test/split/single"
arcpy.env.overwriterOutput = True
outfiles = "D:/test/split/singletif"#输出路径
infiles = "D:/test/split/tif/part3.tif"#要裁剪的tif
clipfiles = arcpy.ListFiles("*.shp")
for filename in clipfiles:
print("Processing:" + filename)
clipputfiles = arcpy.env.workspace + "/" + filename
outputfiles = outfiles + "/" + filename[:-4]
outExtractByMask = ExtractByMask(infiles, clipputfiles)
outExtractByMask.save(outputfiles + ".tif")
print "***OVER***"
print arcpy.GetMessages()
'''
复制栅格,转为8位jpg
'''
arcpy.env.workspace = "D:/test/split/single"
path = "D:/test/split/singletif"#输入栅格路径
filelist = os.listdir(path)
for file in filelist:
if file.endswith(".tif"):
arcpy.CopyRaster_management("D:/test/split/singletif/"+file,"D:/test/split/singlejpg/"+file[:-4]+".jpg","DEFAULTS","0","","","","8_BIT_UNSIGNED")
'''
缩放至同一大小
'''
def resize(old_path, new_path, size, resample):
"""
通过指定的resample方式调整old_path下所有的jpg图片为指定的size,并保存到new_path下
"""
if os.path.isdir(old_path):
for child in os.listdir(old_path):
if child.endswith(".jpg"):
if child.find('.jpg') > 0:
im = Image.open(old_path + child)
im_resized = im.resize(size=size, resample=resample)
if not os.path.exists(new_path):
os.makedirs(new_path)
print(child, 'resize successfully!')
im_resized.save(new_path + child, im.format)
child_path = old_path + child + '/'
resize(child_path, new_path, size, resample)
if __name__ == "__main__":
old_path = 'D:/test/split/singlejpg/'#输入jpg路径
new_path = 'D:/test/split/singlescale/'#输出缩放后的路径
size = (256, 256)
resample = Image.BILINEAR # 使用线性插值法重采样
resize(old_path, new_path, size, resample)
暂时就写这么多啦,做个简单的记录,有问题可以在评论区留言。