- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
摘要: 输入一个图像,通过Segment Anything模型即可获得图像所有目标的分割点位置,再通过位置将图像进行分割保存。
本文分享自华为云社区《 一键分割图像 》,作者:雨落无痕 .
Segment Anything Model(SAM) 通过点或框等输入提示生成高质量的对象分割区域,并且可以用于为图像中的所有对象生成分割区域。它已经在1100万张图像和11亿个分割区域的数据集上进行了训练,并且在各种分割任务上具有强大的零样本性能.
在自然语言处理和最近的计算机视觉领域,最令人兴奋的发展之一是基础模型的发展,这些基础模型可以使用提示技术(prompting)对新数据集和任务执行零样本和小样本学习。我们从这类工作中汲取了灵感.
我们训练 SAM 为任何提示返回有效的分割掩码,其中提示可以是前景/背景点、粗框或掩码、自由格式文本。或者一般来说,提示图像中要分割的内容的任何信息。有效掩码的要求仅仅意味着即使提示不明确并且可能指代多个对象(例如,衬衫上的一个点可能表示衬衫或穿着它的人),输出也应该是一个合理的掩码对象之一。此任务用于预训练模型并通过提示解决一般的下游分割任务.
我们观察到预训练任务和交互式数据收集对模型设计施加了特定的限制。特别是,该模型需要在Web浏览器的CPU上实时运行,以允许我们的标注者实时交互地使用 SAM 以高效地进行标注。虽然运行时限制意味着质量和运行时之间的权衡,但我们发现简单的设计在实践中会产生良好的结果。具体地,图像编码器为图像生成一次性嵌入向量,而轻量级编码器将任何提示实时转换为嵌入向量。然后将这两个信息源组合在一个预测分割掩码的轻量级解码器中。在计算图像嵌入后,SAM 可以在 50 毫秒内根据网络浏览器中的任何提示生成一个分割.
SAM模型 总体上分为3部分:
绿色的 图像编码器 ,基于可扩展和强大的预训练方法,我们使用MAE预训练的ViT,最小限度地适用于处理高分辨率输入。图像编码器对每张图像运行一次,在提示模型之前进行应用.
紫色的 提示编码器 ,考虑两组prompt:稀疏(点、框、文本)和密集(掩码)。我们通过位置编码来表示点和框,并将对 每个提示类型的学习嵌入和自由形式的文本与CLIP中的现成文本编码相加。 密集的提示(即掩码)使用卷积进行嵌入,并通过图像嵌入进行元素求和.
橙色的提示编码器,掩码解码器有效地将图像嵌入、提示嵌入和输出token映射到掩码。该设计的灵感来自于DETR,采用了对(带有动态掩模预测头的)Transformer decoder模块的修改.
使用方法:
输入一个图像,通过Segment Anything模型即可获得图像所有目标的分割点位置,再通过位置将图像进行分割保存.
本案例需使用 Pytorch-1.8 GPU-P100 及以上规格运行 。
点击Run in ModelArts,将会进入到ModelArts CodeLab中,这时需要你登录华为云账号,如果没有账号,则需要注册一个,且要进行实名认证,参考《 ModelArts准备工作_简易版 》 即可完成账号注册和实名认证。登录之后,等待片刻,即可进入到CodeLab的运行环境 。
出现 Out Of Memory ,请检查是否为您的参数配置过高导致,修改参数配置,重启kernel或更换更高规格资源进行规避❗❗❗ 。
为了方便用户下载使用及快速体验,本案例已将代码及segment-anything预训练模型转存至华为云OBS中。模型下载与加载需要几分钟时间.
import os import torch import os.path as osp import moxing as mox path = osp.join(os.getcwd(), ' segment-anything ' ) if not os.path.exists(path): mox.file.copy_parallel( ' obs://modelarts-labs-bj4-v2/case_zoo/segment-anything ' , path) if os.path.exists(path): print( ' Download success ' ) else : raise Exception( ' Download Failed ' ) else : print( " Model Package already exists! " )
check GPU & 安装依赖 。
大约耗时1min 。
%cd segment- anything !pip install -- upgrade pip !pip install torch== 1.12 . 1 torchvision== 0.13 . 1 torchaudio== 0.12 . 1 !pip install opencv- python matplotlib ! python setup.py install import numpy as np import matplotlib.pyplot as plt import cv2 import copy import torch import torchvision print( " PyTorch version: " , torch.__version__) print( " Torchvision version: " , torchvision.__version__) print( " CUDA is available: " , torch.cuda.is_available())
from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor sam_checkpoint = " sam_vit_h_4b8939.pth " model_type = " vit_h " device = " cuda " sam = sam_model_registry[model_type](checkpoint= sam_checkpoint) sam.to(device = device) mask_generator = SamAutomaticMaskGenerator( model = sam, #points_per_side = 32 , #pred_iou_thresh = 0.86 , #stability_score_thresh = 0.92 , #crop_n_layers = 1 , #crop_n_points_downscale_factor = 2 , #min_mask_region_area = 100 , # Requires open-cv to run post- processing )
def show_anns(anns,image): segment_image = copy.copy(image) segment_image.astype( " uint8 " ) if len(anns) == 0 : return sorted_anns = sorted(anns, key=(lambda x: x[ ' area ' ]), reverse= True) for ann in sorted_anns: mask_2d = ann[ ' segmentation ' ] h,w = mask_2d.shape mask_3d_color = np.zeros((h,w, 3 ), dtype= np.uint8) mask = (mask_2d!= 0 ).astype( bool ) rgb = np.random.randint( 0 , 255 , ( 1 , 3 ), dtype= np.uint8) mask_3d_color[mask_2d[:, :] == 1 ] = rgb segment_image[mask] = segment_image[mask] * 0.5 + mask_3d_color[mask] * 0.5 return segment_image image = cv2.imread( ' images/dog.jpg ' ) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) masks = mask_generator.generate(image) segment_image = show_anns(masks,image) fig = plt.figure(figsize=( 25 , 10 )) ax1 = fig.add_subplot( 1 , 2 , 1 ) plt.title( ' Original image ' , fontsize= 16 ) ax1.axis( ' off ' ) ax1.imshow(image) ax2 = fig.add_subplot( 1 , 2 , 2 ) plt.title( ' Segment image ' , fontsize= 16 ) ax2.axis( ' off ' ) ax2.imshow(segment_image) plt.show()
将所有识别出来的分割位置进行分割,并保存成图片.
def apply_mask(image, mask, alpha_channel= True):#应用并且响应mask if alpha_channel: alpha = np.zeros_like(image[..., 0 ])#制作掩体 alpha[mask == 1 ] = 255 #兴趣地方标记为1,且为白色 image = cv2.merge((image[..., 0 ], image[..., 1 ], image[..., 2 ], alpha))#融合图像 else : image = np. where (mask[..., None] == 1 , image, 0 ) return image def mask_image(image, mask, crop_mode_ = True):#保存掩盖部分的图像(感兴趣的图像) if crop_mode_: y, x = np. where (mask) y_min, y_max, x_min, x_max = y.min(), y.max(), x.min(), x.max() cropped_mask = mask[y_min:y_max+ 1 , x_min:x_max+ 1 ] cropped_image = image[y_min:y_max+ 1 , x_min:x_max+ 1 ] masked_image = apply_mask(cropped_image, cropped_mask) else : masked_image = apply_mask(image, mask) return masked_image def save_masked_image(image, filepath): if image.shape[- 1 ] == 4 : cv2.imwrite(filepath, image, [cv2.IMWRITE_PNG_COMPRESSION, 9 ]) else : cv2.imwrite(filepath, image) print(f " Saved as {filepath} " ) def save_anns(anns,image,path): if len(anns) == 0 : return sorted_anns = sorted(anns, key=(lambda x: x[ ' area ' ]), reverse= True) index = 1 for ann in sorted_anns: mask_2d = ann[ ' segmentation ' ] segment_image = copy.copy(image) masked_image = mask_image(segment_image, mask_2d) filename = str(index) + ' .png ' filepath = os.path.join(path, filename) save_masked_image(masked_image, filepath) index = index + 1 save_path = ' result/ ' if not os.path.exists(save_path): os.mkdir(save_path) image = cv2.imread( ' images/dog.jpg ' ) masks = mask_generator.generate(image) save_anns(masks,image,save_path)
为了方便大家使用一键分割案例,当前增加了Gradio可视化部署案例演示.
运行如下代码,Gradio应用启动后可在下方页面进行一键分割图像,您也可以分享public url在手机端,PC端进行访问生成图像.
示例效果如下:
!pip install gradio== 3.24 . 1 def segment_image(image): masks = mask_generator.generate(image) return show_anns(masks,image) def show_image(image): masks = mask_generator.generate(image) if len(masks) == 0 : return sorted_anns = sorted(masks, key=(lambda x: x[ ' area ' ]), reverse= True) index = 1 image_list = [] for ann in sorted_anns: mask_2d = ann[ ' segmentation ' ] segment_image = copy.copy(image) masked_image = mask_image(segment_image, mask_2d) image_list.append(masked_image) return image_list import gradio as gr with gr.Blocks() as demo: with gr.Row(): with gr.Column(): img_in = gr.Image(source= ' upload ' ) with gr.Row(): segment_button = gr.Button( " segment " ,variant= " primary " ) save_button = gr.Button( " segment_images " ,variant= " primary " ) with gr.Row(): with gr.Column(): img_out = gr.Image() with gr.Row(): result_gallery = gr.Gallery(label= ' Output ' , show_label=False, elem_id= " gallery " ).style(grid= 6 , height= ' auto ' ) segment_button.click(segment_image, inputs = [img_in], outputs = [img_out]) save_button.click(show_image, inputs = [img_in], outputs = [result_gallery]) demo.launch(share =True)
Notebook案例地址: 一键分割图像 。
AI Gallery: https://developer.huaweicloud.com/develop/aigallery/home.html 。
速来体验! 。
。
点击关注,第一时间了解华为云新鲜技术~ 。
最后此篇关于抠图党福音:教你一键分割图像的文章就讲到这里了,如果你想了解更多关于抠图党福音:教你一键分割图像的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
实际上我只需要用JAVA编写一个简单的程序来将MySQL INSERTS行转换为CSV文件(每个mysql表等于一个CSV文件) 在JAVA中使用正则表达式是最好的解决方案吗? 我的主要问题是如何正确
我有一个 txt 文件,其格式为: Key:value Key:value Key:value ... 我想将所有键及其值放入我创建的 hashMap 中。如何让 FileReader(file) 或
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度的了解。包括尝试的解决方案、为什么它们不起作用以及预期结果
我每周都会从我的主机下载数据库的备份。它生成一个 .sql 文件,当前大小约为 800mb。此 .sql 文件包含 44 个表。 有什么方法可以通过某些软件将 .sql 文件与所有表分开,以便单独导出
在 iOS 4.0 及更高版本中,有没有一种方法可以在不将整个图像加载到内存的情况下对 CGImage 进行分割?我试图做的是*以编程方式*分割图像,以便在使用大图像的 CATiledLayer 应用
我的 .split() 函数有问题,我有以下字符串: var imageUrl = "Images\Products\randomImage.jpg"; 我想用字符“\”分割,但是,这种情况发生了:
是否可以使用正则表达式将字符串拆分两次?例如,假设我有字符串: example=email@address.com|fname|lname 如何拆分结果为: email@address.com,fna
我正在寻找一种在线程系统(主从)中使用数组的解决方案,它允许我通过用户输入在多个线程上划分矩阵的计算,并将其通过 1 个主线程引导到多个从属线程,这些从属线程计算矩阵的 1 个字段。 我尝试运用我的知
我建立了一个系统来分割包含手写符号的二值图像并对它们进行分类(专门用于音乐)。我知道有商业应用程序可以执行此操作,但这是我尝试将其作为一个项目从头开始。 为了简单起见,假设我的整个图像中有两个元素:
我正在尝试找到一种可接受的复杂性的有效方法 检测图像中的对象,以便将其与周围环境隔离 将该对象分割成它的子部分并标记它们,这样我就可以随意获取它们 我进入图像处理世界已经 3 周了,我已经阅读了很多算
我有一组3D 空间中的点。下图是一个示例: 我想把这些点变成一个面。我只知道点的 X、Y 和 Z 值。例如,查看下图,它显示了从 3D 空间中的点生成的人脸网格。 我在谷歌上搜索了很多,但我找到的是一
我有一个字符串 String placeStr="place1*place2*place3"我想获取包含 place1、place2、place3 的数组,如下所示: String[] places=
我在 Python 中有一个类似于 google.com 的字符串,我想将其分成两部分:google 和 .com。问题是我有一个 URL,例如 subdomain.google.com,我想将其拆分
朋友需要对一个pdf文件进行分割,在网上查了查发现这个pypdf2可以完成这些操作,所以就研究了下这个库,并做一些记录。首先pypdf2是python3版本的,在之前的2版本有一个对应pypdf库。
伙计们,这是一个难以解决的问题,因为它涉及很多硬件细节,所以我想把它放到 EE.SE,但它的主要重点是编程,所以我决定坚持在这里。 我最近怀旧(以及渴望回到 CPU 内在函数),所以我决定自制一个 8
给定 haskell 中的排序列表,我如何获得分段列表,其中连续数字位于同一列表中。例如,如果我有一个排序列表 [1,2,3,4,7,8,10,12,13,15] 结果将是 [[1,2,3 ,4],[
如果我添加三个分割 View ,如下图所示,第三个分割 View (称为 splitView-3)将自动为该分割 View 中的自定义 View 生成约束,例如 customview1 的 Heigh
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
如何为馈送给映射器的文件的每一行提供相同文件的拆分? 基本上我想做的是 for each line in file-split { for each line in file{
带有Snappy压缩功能的ORC文件是否可拆分成条形? 据我所知,Snappy Compressed File是不可拆分的。 但我在博客中读到,快速压缩的文件可以在 strip 上拆分。 真的吗? 最
我是一名优秀的程序员,十分优秀!