引言
街景语义分割是获取街景图像中建成环境要素的重要手段。目前互联网上可以接触到的街景语义分割方法(如Deeplab,PSPNet)大多用五六年前的技术,和SOTA(当下最优)性能差距较大,很多时候不能满足分析需要。
这篇博文介绍使用2023年最新的基于CLIP的开放词类语义分割OV-SEG进行分割。OV-SEG很强大,基本上想分割什么类型都可以,不限于CityScape和ADK20的类型。
OV-SEG
OV-SEG和DeepLab、PSPNet等模型相比,分割精度有显著提升。分割速度也较快,在4090上大概0.5秒完成一张512*512的图像的分割。具体情况可以参阅他们的项目ov-seg github。
对不熟悉深度学习的用户,上手OV-SEG有一定难度(配置繁多)。为此,我改写了OV-SEG调用深度学习模型的接口,便于快速使用OV-SEG,项目链接为https://github.com/kwtk86/ov-seg-easyuse。接下来的语义分割流程都是基于OV-SEG-EASYUSE项目展开的。
快速使用OV-SEG语义分割模型
服务器配置
OV-SEG虽好,但对一般用户有一个缺点:不支持Windows系统,必须在Linux环境下运行。
接下来的所有工作都是在autodl GPU租赁平台上租用的Linux服务器上展开的。如果你没有接触过Linux,接下来的内容有一定操作难度,也易出错。我会在视频版本中,尽可能详细的讲解主要的操作步骤。(当然,如果你有自己的GPU服务器,也可以不用租用autodl的服务器)
视频版本:
(近期会更新)
注册autodl账号
这个没什么好讲的,略过。
创建OV-SEG-EASYUSE镜像的服务器实例
在autodl首页点击【算力市场】
选择有剩余显卡的服务器(推荐西北区的4090)。进入创建实例界面。在【镜像】中,选择【社区镜像】,搜索ov-seg-easyuse并选择。创建镜像。
进入服务器实例
创建后跳转实例界面。实例创建完成、正常运行后,点击【快捷工具】-【JupyterLab】进入笔记本界面。
进入后直接打开的是easyuse_demo.py的代码。这份代码提供了分割示例图片的代码。为运行这份代码,依次点击【+】、【终端】,创建一个新的终端。
进入终端后,输入
cd ov-seg
进入ov-seg目录下。然后输入
python easyuse-demo.py
运行代码。(注:加载模型较慢,可能要十几秒。加载模型后,分割每张图片只需0.5秒左右)
代码运行完后可以在demo_image_masked,demo_image_seg文件夹中找到示例图片的分割结果。我这边只分割了建筑、车辆和树木。要分割其他物体请参考下下节。可见效果还是不错的。
对你自己的数据进行OV-SEG语义分割
分割自己的图片,首先需要将图片打包为zip压缩包,上传到服务器上。
文件上传
改写代码与运行
其他使用说明
OV-SEG-EASYUSE接口说明
配置好服务器后,进入系统盘的ov-seg文件夹
cd ov-seg
在jupyterlab的左侧打开easyuse-demo.py文件,代码的解释都在下面。可以根据自己的需求调整代码。
# 定义字典,作为分割依据。
# 字典有多项,每项的键是需要分割的类型名称,值是保存结果时该类型对应的颜色
# 字典至少一项,至多254项
class_definition = {'building': [255,0,0],
'plants': [0,255,0],
'car': [128,128,0]}
# 传入分割类型定义字典,调用OvSegEasyuse
ose = OvSegEasyuse(class_definition)
img_path = r'./demo_images/2339_118.3473081_34.35914428_180_201804.png'
out_seg_path = r'./demo_images_seg/2339_118.3473081_34.35914428_180_201804.png'
out_masked_path = r'./demo_images_masked/2339_118.3473081_34.35914428_180_201804.png'
# 对每张图像,调用ose.inference_and_save分割。
# inference_and_save有三个参数:img_path, out_seg_path, out_masked_img_path
# img_path: 输入图像的路径(必填)。
# out_seg_path: 输出的分割图路径。必填,后续分析一般基于这张图片及原图开展。
# out_masked_path输出的掩膜图。可选,可用于了解分割结果是否正确,分析一般不基于这张图片展开。
# 可以查看对应文件夹中的示例图片了解更多
# 如果有多张图像,可以自行采取目录遍历等方式进行分割,只要调用inference_and_save就可以
# inference_and_save不仅保存分割结果,也可以返回分割结果。用户可以根据需求对分割结果进行处理。
seg = ose.inference_and_save(img_path, out_seg_path, out_masked_path)
print('finish')
分割结果示例:
原图
分割图,绿色是绿植、红色是建筑、棕黄色是汽车,黑色是没有被分为任何一类的像素
分割图和原图的叠加,效果还行吧。总体感觉比基于Cityscape的模型好了不少。
OV-SEG词类使用技巧
进行分割前,需要先定义类型字典。类型字典中的类型名称最好最好是英文。中文的分割准确性非常不能保证!
class_definition = {'building': [255,0,0],
'plants': [0,255,0],
'car': [128,128,0]}
事实上,还可以多重定义移保证分割准确性。比如需要分割建筑物,可以这样定义:
class_definition = {'building': [255,0,0],
'house': [255,0,0],
'apartment':[255,0,0],
'plants': [0,255,0],
'car': [128,128,0]}
在上面的例子中为了分割出建筑物,字典中加入了多个建筑物的近义词,以防止漏分。building,house,apartment三个类别享有同样的类别色彩标签,也就是把它们分为同一类。
不过这样也可能导致错分,在实际使用时建议多加尝试以确定最合适的类型字典。
在自己的Linux服务器上使用OV-SEG-EASYUSE
和直接调用autodl镜像比略显麻烦。你首先需要配置git。然后:
先克隆项目
git clone https://github.com/kwtk86/ov-seg-easyuse
cd ov-seg-easyuse
如果有梯子可以wget下载
wget https://huggingface.co/spaces/mmlab-ntu/Segment-Any-RGBD/blob/main/ovseg_swinbase_vitL14_ft_mpt.pth
如果挂不了梯子可以从百度网盘下载好再放到服务器上面去。
ovseg_swinbase_vitL14_ft_mpt.pth 百度网盘
然后改写easyuse_demo.py的代码,运行即可。
其他
如果遇到问题可以评论提问,如果觉得有用请点个赞(不止是收藏),谢谢各位。