使用SHP数据批量裁剪TIF图像并转为JPG格式

问题描述

已有数据: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)

暂时就写这么多啦,做个简单的记录,有问题可以在评论区留言。

你可能感兴趣的:(arcgis,python)