在图像处理与计算机视觉领域,图像分割(image segmentation)是在像素级别将一个完整图像划分为若干具有特定语义区域(region)或对象(object)的过程。每个分割区域是一系列拥有相似特征——例如颜色、强度、纹理等的像素集合,因此图像分割也可视为以图像属性为特征空间,为全体像素赋予标签的分类问题。
图像分割是高级图像处理的基础技术,它将原始冗余而繁杂的图像,转化为一种更具意义且简单紧凑的组织形式。在智能安防、卫星遥感、医学影像处理、生物特征识别等领域,图像分割通过提供精简且可靠的图像特征信息,有效地提高后续从而利于后续图像分析、理解等技术的计算效率,具有重要意义。
但是,针对特定任务创建准确的分割模型通常需要技术专家进行高度专业化的标注工作,而近期FaceBook
推出的Segment Anything Model(SAM)项目旨在实现图像分割的大众化。
如果说ChatGPT
是自然语言处理领域的大模型,那SAM
就算是计算机视觉领域的大模型。这次,FaceBook
发布了通用Segment Anything
模型和我们的Segment Anything
10亿掩模数据集SA-1B
——这是有史以来最大的分割数据集,以便实现广泛的应用和促进计算机视觉基础模型的进一步研究。
降低图像分割所需的任务特定建模专业知识、训练计算和自定义数据注释是Segment Anything项目的核心。SAM
已经学习到了物体的通用概念,并且可以为任何图像或任何视频中的任何物体生成掩模,甚至包括它在训练中没有遇到过的物体和图像类型。SAM
足够通用,可以覆盖广泛的用例,并且可以在新的图像“领域”上直接使用——无论是水下照片还是细胞显微镜——而不需要额外的训练——通常被称为零样本迁移能力
将来,SAM可以用于帮助驱动许多领域需要在任何图像中查找和分割任何物体的应用程序
本项目的环境并不复杂,按以下步骤配置即可
克隆库到本地
git clone [email protected]:facebookresearch/segment-anything.git
cd segment-anything; pip install -e .
安装依赖(可选)
这些依赖项用于对掩模进行后处理、将掩模保存为COCO格式以及将模型导出为ONNX格式
pip install opencv-python pycocotools matplotlib onnxruntime onnx
下载模型文件ViT-H SAM model.
测试代码
import torch
import numpy as np
import cv2
import matplotlib.pyplot as plt
from segment_anything import sam_model_registry, SamPredictor
from segment_anything.utils.onnx import SamOnnxModel
import onnxruntime
from onnxruntime.quantization import QuantType
from onnxruntime.quantization.quantize import quantize_dynamic
def show_mask(mask, ax):
color = np.array([30/255, 144/255, 255/255, 0.6])
h, w = mask.shape[-2:]
mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
ax.imshow(mask_image)
checkpoint = "D:\AIProject\segment-anything\sam_vit_h_4b8939.pth"
model_type = "vit_h"
sam = sam_model_registry[model_type](checkpoint=checkpoint)
image = cv2.imread('images/truck.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
predictor = SamPredictor(sam)
predictor.set_image(image)
image_embedding = predictor.get_image_embedding().cpu().numpy()
ort_inputs = {
"image_embeddings": image_embedding,
"point_coords": onnx_coord,
"point_labels": onnx_label,
"mask_input": onnx_mask_input,
"has_mask_input": onnx_has_mask_input,
"orig_im_size": np.array(image.shape[:2], dtype=np.float32)
}
masks, _, low_res_logits = ort_session.run(None, ort_inputs)
plt.figure(figsize=(10,10))
plt.imshow(image)
show_mask(masks, plt.gca())
show_points(input_point, input_label, plt.gca())
plt.axis('off')
plt.show()
原图:
可以到SAM官网体验分割效果,这里以清明上河图为例
我们通过Upload
选项上传清明上河图原图
我们先试试自动分割Everything
,其实效果一般,很多精细的地方没分出来
但这不代表不能进行精细的分割,我们可以点击Hover & Click
选项,接着把鼠标移到图中,就能看到分割的效果。
这个图中主要有三个元素:车夫、推车人和车,现在这三个元素使混合在一起的。可以通过左侧的Remove Area
选项进行更细粒度地分割,比如分割出车夫
SAM的更多应用大家可以进一步发掘。展望未来,像素级别的图像理解与视觉内容的更高级别的语义理解之间更紧密的耦合,将实现更强大的人工智能系统。
更多精彩专栏: