技术研究之遥感图像分割

标签: 无 分类: 未分类 创建时间:2024-11-26 06:06:57 更新时间:2025-01-17 10:39:23

1.前言

经过我多次调研,基本上有点思路了,在 调研报告之遥感影像识别 基础上,进一步对使用 segment-geospatial 对遥感影像分割。

我开始的问题就是:基于语义分割,那么使用 SAM 这样的分割模型,如何做到识别不同的类别呢?比如我输入一个 “土壤”,就会将图片中的全部土壤识别出来了吗?带着这个疑问,我开始了研究。

2.安装

安装示例需要的依赖

1
pip install segment-geospatial groundingdino-py leafmap localtileserver
参考文章:
【1】.【GEO-AI】SAM-Geo库(segment-geospatial)入门教程 这也是一个例子,大致上也是代码仓库的例子。

3.基本示例

这里我用了 proj 路径,指定了坐标系,否则就会报错。还要说明的就是,这个 leafmap.Map 是一个交互地图,需要在 jupyter 中使用,如果单独的一个 python 文件,可能出不来地图,所以最后还是输出一个文件最好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import leafmap
from samgeo import tms_to_geotiff
from samgeo.text_sam import LangSAM
import sys
sys.path.append("..")
sys.path.append(os.path.dirname(sys.path[0]))
from conf import conf
config = conf.getConf()
# 对应自己的python包的安装地址
os.environ['PROJ_LIB'] =r'C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\proj_data'
os.environ['PROJ_DATA'] =r'C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\proj_data'
os.environ['GDAL_DATA'] =r'C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\gdal_data'
rasterio.env.set_proj_data_search_path(r'C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\proj_data')
# 初始化地图
m = leafmap.Map(center=[-22.17615, -51.253043], zoom=18, height="800px")
m.add_basemap("SATELLITE")
# 定义范围,下载一个影像,会在当前文件夹生成一个 Image.tif 影像。
bbox = m.user_roi_bounds()
if bbox is None:
bbox = [-51.2565, -22.1777, -51.2512, -22.175]
image = "Image.tif"
tms_to_geotiff(output=image, bbox=bbox, zoom=19, source="Satellite", overwrite=True)
m.layers[-1].visible = False
# 显示下载的地图
m.add_raster(image, layer_name="Image")
# 初始化分割类
sam = LangSAM()
# 定义语义
text_prompt = "tree"
# 分割影像
sam.predict(image, text_prompt, box_threshold=0.24, text_threshold=0.24)
# 可视化结果,结果会输出到当前文件夹下的 annotations.tif 文件中
sam.show_anns(
cmap="Greens",
add_boxes=False,
alpha=0.5,
title="Automatic Segmentation of Trees",
output="annotations.tif"
)
参考文章:
【1】.Segmenting remote sensing imagery with text prompts and the Segment Anything Model (SAM) 这是官方的例子,分割了 “tree” 这个类别。
【2】.lang-segment-anything Language Segment-Anything 是一个开源项目,它结合了实例分割和文本提示的强大功能,为图像中的特定对象生成蒙版。
【3】.python 获取脚本所在目录的正确方法 这里通过 os.path.split(os.path.realpath(file))[0] 获取了路径。
【4】.python获取程序执行文件路径方法
【5】.【AI-Fix】解决地图展示包leafmap在Jupyter NoteBook中地图不显示的问题

4.计算面积

5.图像合并

遥感影像在利用语义分割模型进行训练的时候,往往是裁剪成小图进行训练,预测时候时候需要将整张遥感影像切割成小图进行预测,再拼接回去,

参考文章:
【1】.遥感语义分割切图预测之后再拼接 这里提供了分割和合并的代码。

问题

1.Connection to huggingface.co timed out

进行分割的时候,会下载一份数据,结果就是死活下载不下来。挂了代理之后,我查看了下载内容,这个 https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth 下载的东西最多,足足有 2.39 G。

下载了:GroundingDINO_SwinB.cfg.py、tokenizer_config.json、config.json、vocab.txt、tokenizer.json:、model.safetensors、groundingdino_swinb_cogcoor.pth、sam_vit_h_4b8939.pth

【解决方案】
(1)第一个解决方案,那就是使用代理,设置系统代理。

(2)第二个解决方案就是修改源码,好像更加的麻烦。

1
2
3
4
5
6
7
Step 1: download necessary files listed in huggingface-bert-base-uncased, including config.json, flax_model.msgpack, pytorch_model.bin, tf_model.h5, tokenizer.json, tokenizer_config.json, vocab.txt

Step 2: put downloaded files (Step 1) into your local folder. For example, the local folder could be Grounded-Segment-Anything/huggingface/bert-base-uncased

Step 3: modify text_encoder_type in get_tokenlizer.py#L17 and get_tokenlizer.py#L23 to your local folder (defined in Step 2)

Step 4: run the model and enjoy it
参考文章:
【1】.完美解决:Failed to connect to huggingface.co port 443 after 75018 ms Operation timed out 这里有两种方案,一种就是使用 pycrawlers 这个东西,另外一种也是使用代理。
【2】.SAM-Track online / offline配置 那么从这个站点下载需要的文件:bert-base-uncased,下载这几个,
例如放在新建的bert_base文件夹,在Segment-and-Track-Anything/bert_base.
【3】请问,离线运行,配置文件需要修改哪些地方?需要下载哪些文件? 这里有一个步骤,就是修改源码,但是觉得很麻烦。
【4】. [BUG/Help] 20230507晚遇到:huggingface.co 无法访问并获取token配置文件! #950 这里有一个地方,os.environ[“HF_ENDPOINT”] = “https://hf-mirror.com",说是可以解决,但是我没有尝试。

2.rasterio.errors.CRSError: The EPSG code is unknown.

在执行代码的时候,出现了问题:ROJ: proj_create_from_database: C:\Program Files\PostgreSQL\15\share\contrib\postgis-3.4\proj\proj.db contains DATABASE.LAYOUT.VERSION.MINOR = 2 whereas a number >= 4 is expected. It comes from another PROJ installation.
这个问题就是 proj 的版本问题,我在 gdal 安装的时候,配置过这个问题,但是弄到这里,不行了,还是报错:File “rasterio\crs.pyx”, line 592, in rasterio.crs.CRS.from_epsg

【尝试方案】
(1)尝试设置 os.environ[‘PROJ_LIB’],结果不行。
(2)尝试输出 proj,设置的环境变量没有效果。

1
2
import rasterio
rasterio.show_versions()

结果还是输出了:
PROJ DATA: C:\Program Files\PostgreSQL\15\share\contrib\postgis-3.4\proj
GDAL DATA: C:\Program Files\PostgreSQL\15\gdal-data

(3)尝试设置 os.environ[‘PROJ_DATA’],无效。

(4)我查看了 rasterio 的代码,主要在C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\env.py 这个文件里面,有关于 ‘PROJ_DATA’ 这个变量的说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if "PROJ_DATA" in os.environ:
# PROJ 9.1+
path = os.environ["PROJ_DATA"]
set_proj_data_search_path(path)
elif "PROJ_LIB" in os.environ:
# PROJ < 9.1
path = os.environ["PROJ_LIB"]
set_proj_data_search_path(path)

elif PROJDataFinder().search_wheel():
path = PROJDataFinder().search_wheel()
log.debug("PROJ data found in package: path=%r.", path)
set_proj_data_search_path(path)

# See https://github.com/rasterio/rasterio/issues/1631.
elif PROJDataFinder().has_data():
log.debug("PROJ data files are available at built-in paths.")

else:
path = PROJDataFinder().search()

if path:
log.debug("PROJ data found in other locations: path=%r.", path)
set_proj_data_search_path(path)

通过 set_proj_data_search_path 设置 proj 的路径,虽然能解决了 proj 路径的问题,但是这个 “number >= 4 is expected” 问题还是存在。

1
2
import rasterio
rasterio.env.set_proj_data_search_path(os.environ['PROJ_DATA'])

(5)尝试安装 proj-data,我觉得安装了没有用,也没有地方去设置这个东西。

1
conda install -c conda-forge proj-data

【解决方案】
(1)我重新找了 pro_data 路径,发现 rasterio 自带了 pro_data,在路径:C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\proj_data,于是我就重新指定了 pro_data 的路径,也就是我的虚拟环境的 yolo 安装路径里面。

1
2
3
import rasterio
rasterio.env.set_proj_data_search_path(r'C:\Soft\anaconda3\envs\yolo\Lib\site-packages\rasterio\proj_data')
rasterio.show_versions()

(2)然后接下来还有一个问题,那就是有一个地方(C:\Soft\anaconda3\envs\yolo\lib\site-packages\osgeo\osr.py”)总是依赖 C:\Soft\anaconda3\envs\yolo\Library\share\proj\proj.db 这个db,还是会报:DATABASE.LAYOUT.VERSION.MINOR = 2 whereas a number >= 3 is expected 错误,于是我就把上面路径中的 rasterio\proj_data 中的 proj.db,替换了 Library\share\proj 中的 proj.db,这才算是解决了报错的问题。

至于为什么,以及为什么要改,我暂时无法理解。

参考文章:
【1】.【Anaconda环境下rasterio解决ERROR 1: PROJ: proj_create_from_database: Cannot find proj.db】 添加环境变量 os.environ[‘PROJ_LIB’]
【2】.http://www.spatial.pro/2024/09/20/Python-%E4%B8%AD%E7%9A%84proj.db%E5%86%B2%E7%AA%81%E6%9A%82%E6%97%B6%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/
【3】.rasterio Documentation rasterio的用户手册。
【4】.Proj4的安装 要在Python中使用Proj4,首先需要安装其Python绑定库 pyproj
【5】.Proj.db version mismatch 这个没啥用。
【6】.Installation
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。