图片/nparray转成shapefile文件


前言

一、数组转成shapefile文件函数

第一步:使用cv2.findContours把图片轮廓

这些轮廓contours是一个list,list里面是array。array格式是(x,y)类似坐标

第二步:把数组转成gdal用的数据

把contours的(x,y)点,保存起来,按照如下格式,保存在binary_value.txt中

x0 y0
x1 y1
x2 y2

第三步:从txt中取数据使用gdal生成shapefile文件

def nparray2shp(file_path_jpg, folder_2_shpimg, DATASET, Imarray):
    Image.fromarray(np.uint8(Imarray)).save(file_path_jpg)
        
    #.jpg trans to .shp
    np.set_printoptions(threshold=np.inf)
    img = cv2.imread(file_path_jpg)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(img, contours, -1, (0, 0, 255), 1)
    cv2.imwrite(folder_2_shpimg+DATASET+'_contour.jpg', img)
    
    # (binary) is the binary image; contours's class is List 
    file = open('binary_value.txt', 'w')    
    for i in range(len(contours)):
        for j in range(len(contours[i])):
            temstr = str(contours[i][j])+'\n'
            temstr=temstr.replace('[','')
            temstr=temstr.replace(']','')
            temstr = temstr.split()
            file.write(str(temstr[0]+ ' '+str(temstr[1]))+'\n')
    file.close()
    
    gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO")
    gdal.SetConfigOption("SHAPE_ENCODING","GB2312")
    ogr.RegisterAll()
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326) 
    driver = ogr.GetDriverByName("ESRI Shapefile")
    dataSource = driver.CreateDataSource(folder_2_shpimg+DATASET+".shp")   
    layer = dataSource.CreateLayer(DATASET, srs,ogr.wkbPoint)    
    field_list = []    
    f_name= ['x_long','y_lat']
    for i in range(len(f_name)):       
       field_name = f_name[i]
       field_list.append(field_name)
       field = ogr.FieldDefn(field_name, ogr.OFTString)
       field.SetWidth(100)
       layer.CreateField(field)
     
     # row and col
    file2 = open('binary_value.txt', 'r')
    for line in file2:
        feature = ogr.Feature(layer.GetLayerDefn())
        geom = ogr.Geometry(ogr.wkbPoint)
        geom.AddPoint(float(line.split(' ')[0]), -float(line.split(' ')[1])) 
        feature.SetGeometry(geom)         
        for j in range(2):
             feature.SetField(field_list[j], line.split(' ')[j])
        layer.CreateFeature(feature)
    os.remove('./binary_value.txt')
    os.remove(file_path_jpg)

效果图

在这里插入图片描述

### 使用 Segment Anything 模型进行遥感图像分割 #### 准备工作 为了使用 Segment Anything Model (SAM) 进行遥感图像的分割,需先安装必要的库并加载预训练模型。这通常涉及配置环境变量和导入所需的Python包。 ```python import torch from segment_anything import sam_model_registry, SamPredictor import cv2 import numpy as np ``` #### 加载模型与初始化预测器 指定 `image_path` 和 `sam_checkpoint` 参数来指明输入图片的位置以及之前下载好的 SAM 权重文件位置;同时定义使用的设备(CPU 或 GPU)及所选模型版本[^2]。 ```python def load_sam(model_type="vit_b", device='cuda'): checkpoint_url = "path/to/sam_vit_b_01ec64.pth" model = sam_model_registry[model_type](checkpoint=checkpoint_url).to(device=device) predictor = SamPredictor(model) return predictor ``` #### 图像读取与处理 针对特定的应用场景——即地理遥感中的卫星影像,需要确保能够正确解析多光谱或高分辨率的数据集格式,比如GeoTIFF文件。这里假设已经有一个合适的函数可以从给定路径中读入此类图像,并将其转换成适合喂给神经网络的形式。 ```python def read_image(image_path): img = cv2.imread(image_path) img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) return img_rgb ``` #### 执行分割操作 利用上述准备好的工具链,在实际执行阶段只需调用简单的API接口即可完成目标区域的选择与掩码生成过程。对于遥感领域而言,这意味着可以根据兴趣点自动勾勒出边界轮廓,从而辅助后续的空间分析任务[^1]。 ```python predictor = load_sam() img = read_image('sentinel2.tif') predictor.set_image(img) input_point = np.array([[500, 375]]) # 用户交互式点击得到的兴趣点坐标 input_label = np.array([1]) # 对应标签(前景/背景),此处设为前景 masks, scores, logits = predictor.predict( point_coords=input_point, point_labels=input_label, multimask_output=True, ) ``` #### 输出结果保存 最后一步是将获得的结果导出至外部存储介质以便进一步查看或与其他GIS软件集成。此部分涉及到创建Shapefile或其他矢量图形文件的操作。 ```python import shapely.geometry import geopandas as gpd mask = masks[np.argmax(scores)] # 获取最佳匹配度下的二值化蒙版图层 polygons = [] for i in range(mask.shape[-1]): contours, _ = cv2.findContours((mask[:, :, i]*255).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) polygon = [shapely.geometry.Polygon(contour.reshape(-1, 2)) for contour in contours if len(contour)>2] polygons.extend(polygon) gdf = gpd.GeoDataFrame({'geometry': polygons}) gdf.to_file(filename='output.shp', driver='ESRI Shapefile') ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值