使用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)

提示:如果用shp数据裁剪栅格图像时,裁剪出的图像是矩形而不是shp文件的边界,将待裁剪的栅格图像nodata值设置为空值即可解决。

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

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aaaq_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值