图像处理:裁剪卫星影像.tif图片为多个图片,同时保持各图片的空间位置不变

语言:Python,主要函数包:gdal,代码如下:

import gdal

# 读取要切的原图
in_ds = gdal.Open("1060_50.tif")
print("open tif file succeed")
width = in_ds.RasterXSize                         # 获取数据宽度
height = in_ds.RasterYSize                        # 获取数据高度
outbandsize = in_ds.RasterCount                   # 获取数据波段数
im_geotrans = in_ds.GetGeoTransform()             # 获取仿射矩阵信息
im_proj = in_ds.GetProjection()                   # 获取投影信息
datatype = in_ds.GetRasterBand(1).DataType
im_data = in_ds.ReadAsArray()                     #获取数据 

# 读取原图中的每个波段
in_band1 = in_ds.GetRasterBand(1)
in_band2 = in_ds.GetRasterBand(2)
in_band3 = in_ds.GetRasterBand(3)

# 定义切图的起始点坐标
offset_x = 0  
offset_y = 0

#offset_x = width/2  # 这里是随便选取的,可根据自己的实际需要设置
#offset_y = height/2

# 定义切图的大小(矩形框)
block_xsize = 100  # 行
block_ysize = 100  # 列

k=0
for i in range(width//block_xsize):
    for j in range(height//block_xsize):
        out_band1 = in_band1.ReadAsArray(i*block_xsize, j*block_xsize, block_xsize, block_ysize)
        out_band2 = in_band2.ReadAsArray(i*block_xsize, j*block_xsize, block_xsize, block_ysize)
        out_band3 = in_band3.ReadAsArray(i*block_xsize, j*block_xsize, block_xsize, block_ysize)
        print(out_band3)
        k+=1

## 从每个波段中切需要的矩形框内的数据(注意读取的矩形框不能超过原图大小)
#out_band1 = in_band1.ReadAsArray(offset_x, offset_y, block_xsize, block_ysize)
#out_band2 = in_band2.ReadAsArray(offset_x, offset_y, block_xsize, block_ysize)
#out_band3 = in_band3.ReadAsArray(offset_x, offset_y, block_xsize, block_ysize)

# 获取Tif的驱动,为创建切出来的图文件做准备
        gtif_driver = gdal.GetDriverByName("GTiff")

# 创建切出来的要存的文件(3代表3个不都按,最后一个参数为数据类型,跟原文件一致)
        out_ds = gtif_driver.Create(str(k)+'clip4.tif', block_xsize, block_ysize, outbandsize, datatype)
#print("create new tif file succeed")

        # 获取原图的原点坐标信息
        ori_transform = in_ds.GetGeoTransform()
        if ori_transform:
            print (ori_transform)
            print("Origin = ({}, {})".format(ori_transform[0], ori_transform[3]))
            print("Pixel Size = ({}, {})".format(ori_transform[1], ori_transform[5]))
        
        # 读取原图仿射变换参数值
        top_left_x = ori_transform[0]  # 左上角x坐标
        w_e_pixel_resolution = ori_transform[1] # 东西方向像素分辨率
        top_left_y = ori_transform[3] # 左上角y坐标
        n_s_pixel_resolution = ori_transform[5] # 南北方向像素分辨率
        
        # 根据反射变换参数计算新图的原点坐标
        top_left_x = top_left_x + i*block_xsize * w_e_pixel_resolution
        top_left_y = top_left_y + j*block_xsize * n_s_pixel_resolution
        
        # 将计算后的值组装为一个元组,以方便设置
        dst_transform = (top_left_x, ori_transform[1], ori_transform[2], top_left_y, ori_transform[4], ori_transform[5])
        
        # 设置裁剪出来图的原点坐标
        out_ds.SetGeoTransform(dst_transform)
        
        # 设置SRS属性(投影信息)
        out_ds.SetProjection(in_ds.GetProjection())
        
        # 写入目标文件
        out_ds.GetRasterBand(1).WriteArray(out_band1)
        out_ds.GetRasterBand(2).WriteArray(out_band2)
        out_ds.GetRasterBand(3).WriteArray(out_band3)
        
        # 将缓存写入磁盘
        out_ds.FlushCache()
        print("FlushCache succeed")
        
        # 计算统计值
        # for i in range(1, 3):
        #     out_ds.GetRasterBand(i).ComputeStatistics(False)
        # print("ComputeStatistics succeed")
        
        del out_ds
        
        print("End!")

 

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
好的,你可以按照以下步骤进行操作: 1. 引入头文件 ```c++ #include "gdal_priv.h" #pragma comment(lib, "gdal_i.lib") ``` 2. 打开原始影像 ```c++ GDALAllRegister(); GDALDataset* poSrcDS = (GDALDataset*)GDALOpen("原始影像路径", GA_ReadOnly); if (poSrcDS == NULL) { printf("无法打开原始影像!\n"); return; } ``` 3. 定义裁剪区域 ```c++ double adfGeoTransform[6]; poSrcDS->GetGeoTransform(adfGeoTransform); // 获取原始影像的地理转换参数 int nXSize = poSrcDS->GetRasterXSize(); // 获取原始影像宽度 int nYSize = poSrcDS->GetRasterYSize(); // 获取原始影像高度 double dfMinX = /*裁剪区域左上角点的横坐标*/; double dfMaxX = /*裁剪区域右下角点的横坐标*/; double dfMinY = /*裁剪区域左上角点的纵坐标*/; double dfMaxY = /*裁剪区域右下角点的纵坐标*/; int nMinX = (int)((dfMinX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.5); // 计算左上角点的列号 int nMaxX = (int)((dfMaxX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.5); // 计算右下角点的列号 int nMinY = (int)((dfMaxY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.5); // 计算左上角点的行号 int nMaxY = (int)((dfMinY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.5); // 计算右下角点的行号 int nWidth = nMaxX - nMinX + 1; // 计算裁剪影像的宽度 int nHeight = nMaxY - nMinY + 1; // 计算裁剪影像的高度 ``` 4. 创建裁剪影像 ```c++ GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); // 获取TIFF格式的驱动 GDALDataset* poDstDS = poDriver->Create("E:\\t1.tif", nWidth, nHeight, poSrcDS->GetRasterCount(), poSrcDS->GetRasterBand(1)->GetDataType(), NULL); // 创建裁剪影像 if (poDstDS == NULL) { printf("无法创建裁剪影像!\n"); return; } double adfDstGeoTransform[6] = { adfGeoTransform[0] + nMinX * adfGeoTransform[1], adfGeoTransform[1], 0, adfGeoTransform[3] + nMinY * adfGeoTransform[5], 0, adfGeoTransform[5] }; // 计算裁剪影像的地理转换参数 poDstDS->SetGeoTransform(adfDstGeoTransform); // 设置裁剪影像的地理转换参数 ``` 5. 裁剪影像 ```c++ for (int i = 1; i <= poSrcDS->GetRasterCount(); i++) { GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(i); // 获取原始影像的波段 GDALRasterBand* poDstBand = poDstDS->GetRasterBand(i); // 获取裁剪影像的波段 poSrcBand->RasterIO(GF_Read, nMinX, nMinY, nWidth, nHeight, poDstBand->GetLockedBlockRef(), nWidth, nHeight, poSrcBand->GetRasterDataType(), 0, 0); // 裁剪影像 } ``` 6. 释放资源 ```c++ GDALClose(poSrcDS); // 释放原始影像的资源 GDALClose(poDstDS); // 释放裁剪影像的资源 ``` 完成上述步骤后,你就可以成功地使用C++版GDAL裁剪一幅tif影像,并将其另存为"E:\\t1.tif"了。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值