将labelme json 转换为shapefile

最近遇到一个小问题:

如何将我在labelme上勾的Json 文件转变为shapefile呢?

这个问题困扰我的主要原因是labelme的json文件和我平常见到的json文件有点不太一样。labelme的json中的坐标是相对于其附属的图像的左上角原点的以像素为单位的距离(x,y),因此需要将它转变为地理坐标。这就需要用到其附属的图像的geotransform信息。

主要的解决思路就是:

1)根据附属图像提取地理位置信息

2)提取json中的shapes, 获取每一个point的坐标

3)根据关系将point的坐标变换为地理坐标

4)利用geopandas 创建矢量并导出

代码如下

import json
import geopandas as gpd
from shapely.geometry import Polygon
from osgeo import gdal
import glob
from tqdm import tqdm

# 批量读取 Labelme 导出的 JSON 文件
folder_path = 'your/folder/path'
json_paths = glob.glob(folder_path + '*.json')
json_paths

def labelme_json_to_shapefile(labelme_json_path, output_shapefile_path):
    with open(labelme_json_path, 'r') as f:
        data = json.load(f)
    #读取跟json文件相关的影像信息
    image_width = data['imageWidth']
    image_height = data['imageHeight']
    geometries = []

    imagepath = folder_path + data['imagePath'].split('\\')[-1]
    image = gdal.Open(imagepath)

    geotrans = image.GetGeoTransform()
    x0 = geotrans[0]
    y0 = geotrans[3]
    x_resolution = geotrans[1]
    y_resolution = geotrans[5]

    # 处理每个标注对象
    for shape in data['shapes']:
        label = shape['label']
        points = shape['points']

        # 将相对坐标转换为绝对坐标
        polygon_coords = [(x0+point[0]*x_resolution, y0+point[1]*y_resolution) for point in points]

        # 创建 shapely Polygon 对象
        polygon = Polygon(polygon_coords)

        # 添加到 geometries 列表中
        geometries.append({'label': label, 'geometry': polygon})

    # 创建 GeoDataFrame
    gdf = gpd.GeoDataFrame(geometries, geometry='geometry')
    gdf.crs = 'EPSG:32644'
    gdf.to_file(output_shapefile_path, driver='ESRI Shapefile')

for json_path in tqdm(json_paths):
    output_shp_path = 'your/folder/path'+json_path.split('\\')[-1].replace('.json', '.shp')
    labelme_json_to_shapefile(json_path, output_shp_path)

'''

这里需要注意的是坐标系(EPSG)需要改成适合你自己的坐标系。

'''

结果如下,成功了~

欢迎关注我和我的公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值