segment-anything本地部署使用

news2024/11/28 19:34:36

前言
Segment Anything Model(SAM)是一种先进的图像分割模型,它基于Facebook AI在2020年发布的Foundation Model3,能够根据简单的输入提示(如点或框)准确地分割图像中的任何对象,并且无需额外训练就能适应不熟悉的对象和图像4。它利用了传统的计算机视觉技术和深度学习算法,在一个涵盖1100万张图片和11亿个掩码的庞大数据集上进行了训练,展现出了卓越的零样本性能。

1: 环境及软件
win10
Miniconda3 (自行安装,网上一堆教程,这里不介绍了)
GPU (rtx 3060TI 8G)

2:安装
官方说明
在这里插入图片描述

1> 下载segment-anything
下载地址: https://github.com/facebookresearch/segment-anything
解压随便放个目录下
这里放在 F:\gameai\segment-anything
在这里插入图片描述
2>模型数据下载地址
模型文件下载放到segment-anything 目录下就行
default or vit_h:
https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth

vit_l:
https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth

vit_b:
https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth

3>创建conda 环境
<1>点击 Anaconda Prompt(Miniconda3) 打开conda命令界面
在这里插入图片描述
<2> 创建虚拟环境 (环境名 segment-anything)
conda create -n segment-anything python=3.10 #创建环境并安装python3.10
conda activate segment-anything #进入环境

【1】 进入 https://pytorch.org/get-started/locally/ 根据自己的配置 生成 运行命令
本地用的是 cuda11.7
查看本地cuda版本
cmd
nvidia-smi
在这里插入图片描述

在这里插入图片描述
在segment-anything 环境下 执行
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
在这里插入图片描述
测试Pytorch 是否开启了GPU
显示True 表示OK在这里插入图片描述
退出 python 命令 exit()

 cd segment-anything
 pip install -e . 
 pip install opencv-python pycocotools matplotlib onnxruntime onnx

创新2个目录input output
模型也放这里
在这里插入图片描述

input 里随便放一章图片(这里先放入segment-anything\assets\notebook2.png)


**3:测试**

```bash
python scripts/amg.py --checkpoint sam_vit_h_4b8939.pth --model-type vit_h --input F:\gameai\segment-anything\input --output F:\gameai\segment-anything\output

网上找的一个脚本(具体地址忘了,别人写的) 点击选择区域
test.py 内容如下

import cv2
import os
import numpy as np
from segment_anything import sam_model_registry, SamPredictor

input_dir = 'input'
output_dir = 'output'
crop_mode=True#是否裁剪到最小范围
#alpha_channel是否保留透明通道
print('最好是每加一个点就按w键predict一次')
os.makedirs(output_dir, exist_ok=True)
image_files = [f for f in os.listdir(input_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg','.JPG','.JPEG','.PNG'))]

sam = sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
_ = sam.to(device="cuda")#注释掉这一行,会用cpu运行,速度会慢很多
predictor = SamPredictor(sam)#SAM预测图像
def mouse_click(event, x, y, flags, param):#鼠标点击事件
    global input_point, input_label, input_stop#全局变量,输入点,
    if not input_stop:#判定标志是否停止输入响应了!
        if event == cv2.EVENT_LBUTTONDOWN :#鼠标左键
            input_point.append([x, y])
            input_label.append(1)#1表示前景点
        elif event == cv2.EVENT_RBUTTONDOWN :#鼠标右键
            input_point.append([x, y])
            input_label.append(0)#0表示背景点
    else:
        if event == cv2.EVENT_LBUTTONDOWN or event == cv2.EVENT_RBUTTONDOWN :#提示添加不了
            print('此时不能添加点,按w退出mask选择模式')


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 apply_color_mask(image, mask, color, color_dark = 0.5):#对掩体进行赋予颜色
    for c in range(3):
        image[:, :, c] = np.where(mask == 1, image[:, :, c] * (1 - color_dark) + color_dark * color[c], image[:, :, c])
    return image

def get_next_filename(base_path, filename):#进行下一个图像
    name, ext = os.path.splitext(filename)
    for i in range(1, 101):
        new_name = f"{name}_{i}{ext}"
        if not os.path.exists(os.path.join(base_path, new_name)):
            return new_name
    return None

def save_masked_image(image, mask, output_dir, filename, crop_mode_):#保存掩盖部分的图像(感兴趣的图像)
    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)
    filename = filename[:filename.rfind('.')]+'.png'
    new_filename = get_next_filename(output_dir, filename)
    
    if new_filename:
        if masked_image.shape[-1] == 4:
            cv2.imwrite(os.path.join(output_dir, new_filename), masked_image, [cv2.IMWRITE_PNG_COMPRESSION, 9])
        else:
            cv2.imwrite(os.path.join(output_dir, new_filename), masked_image)
        print(f"Saved as {new_filename}")
    else:
        print("Could not save the image. Too many variations exist.")

current_index = 0

cv2.namedWindow("image")
cv2.setMouseCallback("image", mouse_click)
input_point = []
input_label = []
input_stop=False
while True:
    filename = image_files[current_index]
    image_orign = cv2.imread(os.path.join(input_dir, filename))
    image_crop = image_orign.copy()#原图裁剪
    image = cv2.cvtColor(image_orign.copy(), cv2.COLOR_BGR2RGB)#原图色彩转变
    selected_mask = None
    logit_input= None
    while True:
        #print(input_point)
        input_stop=False
        image_display = image_orign.copy()
        display_info = f'{filename} | Press s to save | Press w to predict | Press d to next image | Press a to previous image | Press space to clear | Press q to remove last point '
        cv2.putText(image_display, display_info, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2, cv2.LINE_AA)
        for point, label in zip(input_point, input_label):#输入点和输入类型
            color = (0, 255, 0) if label == 1 else (0, 0, 255)
            cv2.circle(image_display, tuple(point), 5, color, -1)
        if selected_mask is not None :
            color = tuple(np.random.randint(0, 256, 3).tolist())
            selected_image = apply_color_mask(image_display,selected_mask, color)

        cv2.imshow("image", image_display)
        key = cv2.waitKey(1)

        if key == ord(" "):
            input_point = []
            input_label = []
            selected_mask = None
            logit_input= None
        elif key == ord("w"):
            input_stop=True
            if len(input_point) > 0 and len(input_label) > 0:
                #todo 预测图像
                predictor.set_image(image)#设置输入图像
                input_point_np = np.array(input_point)#输入暗示点,需要转变array类型才可以输入
                input_label_np = np.array(input_label)#输入暗示点的类型
                #todo 输入暗示信息,将返回masks
                masks, scores, logits= predictor.predict(
                    point_coords=input_point_np,
                    point_labels=input_label_np,
                    mask_input=logit_input[None, :, :] if logit_input is not None else None,
                    multimask_output=True,
                )

                mask_idx=0
                num_masks = len(masks)#masks的数量
                while(1):
                    color = tuple(np.random.randint(0, 256, 3).tolist())#随机列表颜色,就是
                    image_select = image_orign.copy()
                    selected_mask=masks[mask_idx]#选择msks也就是,a,d切换
                    selected_image = apply_color_mask(image_select,selected_mask, color)
                    mask_info = f'Total: {num_masks} | Current: {mask_idx} | Score: {scores[mask_idx]:.2f} | Press w to confirm | Press d to next mask | Press a to previous mask | Press q to remove last point | Press s to save'
                    cv2.putText(selected_image, mask_info, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2, cv2.LINE_AA)
                    #todo 显示在当前的图片,
                    cv2.imshow("image", selected_image)

                    key=cv2.waitKey(10)
                    if key == ord('q') and len(input_point)>0:
                        input_point.pop(-1)
                        input_label.pop(-1)
                    elif key == ord('s'):
                        save_masked_image(image_crop, selected_mask, output_dir, filename, crop_mode_=crop_mode)
                    elif key == ord('a') :
                        if mask_idx>0:
                            mask_idx-=1
                        else:
                            mask_idx=num_masks-1
                    elif key == ord('d') :
                        if mask_idx<num_masks-1:
                            mask_idx+=1
                        else:
                            mask_idx=0
                    elif key == ord('w') :
                        break
                    elif key == ord(" "):
                        input_point = []
                        input_label = []
                        selected_mask = None
                        logit_input= None
                        break
                logit_input=logits[mask_idx, :, :]
                print('max score:',np.argmax(scores),' select:',mask_idx)

        elif key == ord('a'):
            current_index = max(0, current_index - 1)
            input_point = []
            input_label = []
            break
        elif key == ord('d'):
            current_index = min(len(image_files) - 1, current_index + 1)
            input_point = []
            input_label = []
            break
        elif key == 27:
            break
        elif key == ord('q') and len(input_point)>0:
            input_point.pop(-1)
            input_label.pop(-1)
        elif key == ord('s') and selected_mask is not None :
            save_masked_image(image_crop, selected_mask, output_dir, filename, crop_mode_=crop_mode)

    if key == 27:
        break

运行结果如下
在这里插入图片描述

操作
先按 w
鼠标左键 选择点 ,可以多点击下
鼠标右键 选择背景
根据上面提示 自行选择
轮廓闪时,按w确认/按d下个轮廓/
Score 分数越大越好
确认后 按s 保存轮廓到 output 目录下(这里选择了狗,在狗头上点了一下)
在这里插入图片描述
还是比较精确的,就是不太圆滑,有点提升

如果觉得有用,麻烦点个赞,加个收藏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

将项目导入到github全过程

新建仓库 完善仓库信息 然后点击创建仓库 复制仓库地址 将文件上传到git上 我这里要上传IMProject文件夹&#xff0c;所以就在这个文件夹内部&#xff0c;右键鼠标&#xff0c;然后点击git bash here 输入git init &#xff0c;然后文件夹里面就会多一个.git文件 输入gi…

【IoT】ChatGPT 与 AI 硬件

随着AI的发展&#xff0c;比如最近炒得很火的ChatGPT&#xff0c;还在持续快速迭代更新。 当然了&#xff0c;对于软件和算法&#xff0c;如果你想&#xff0c;每天迭代 10 个版本都可以。 包括科大讯飞的星火认知大模型最近也刚发布。 这就引出了未来一个更大的发展方向&am…

PMP课堂模拟题目及解析(第7期)

61. 为限制项目变更的数量&#xff0c;项目经理制定了严格的变更管理计划&#xff0c;只允许批准减轻重大潜在或实际风险的变更&#xff0c;一位团队成员提出了一个范围变更&#xff0c;该变更将消除对一个落后于进度计划的外部项目的依赖关系。项目经理应该怎么做&#xff1f…

AI绘图实战(九):给热门歌曲做配图 | Stable Diffusion成为设计师生产力工具

S&#xff1a;AI能取代设计师么&#xff1f; I &#xff1a;至少在设计行业&#xff0c;目前AI扮演的主要角色还是超级工具&#xff0c;要顶替&#xff1f;除非甲方对设计效果无所畏惧~~ 预先学习&#xff1a; 安装及其问题解决参考&#xff1a;《Windows安装Stable Diffusion …

迎接新时代挑战:项目管理中的创新与发展

你想知道如何在你的 PM 角色中保持最新状态吗&#xff1f; 您所在的行业是否发展如此之快&#xff0c;以至于有一天您可能不再需要您&#xff1f; 随着人工智能、敏捷和授权团队的兴起&#xff0c;项目经理还需要吗&#xff1f;也许吧&#xff0c;但不是出于您可能期望的原因。…

@vant/weapp

文章目录 一、介绍二、安装1. cd 到项目文件目录2. 使用 npm 安装3. 修改项目配置4. 构建5. 其他文件 三、使用四、【参考】 微信小程序使用vant/weapp组件 一、介绍 Vant 是一个开源的移动端组件库&#xff0c;在微信小程序开发中可以使用该UI库提提供的组件。 使用这个三方…

用户分享 | Dockquery,一个国产数据库客户端的初体验

DockQuery 有话说 DockQuery &#xff0c;「天狼」也&#xff0c;中原本土狼种。天狼年纪很小&#xff0c;不满一岁&#xff0c;但它有一个伟大的梦想——建造一座能容纳中原群狼的宫殿&#xff01;它不想再被异域狼欺负&#xff0c;不想被异域狼群挤占生存空间&#xff0c;它…

点到直线距离估计线性回归参数

点到直线距离估计线性回归参数 文章目录 点到直线距离估计线性回归参数[toc]1 推导2 模拟 1 推导 普通最小二乘法(OLS)估计线性回归方程的参数要求残差平方和最小&#xff0c;通过优化方法计算出各参数的估计量。其中残差 e i y i − β 0 − β 1 x i e_iy_i-\beta_0-\beta…

docker安装Nexus3搭建docker私有仓库,并上传镜像

参考&#xff1a;https://blog.csdn.net/gengkui9897/article/details/127353727 nexus3支持的私有库 支持maven(java)、npm&#xff08;js&#xff09;、docker、herm、yum、apt、pypi(python)go、等等 1. 下载安装docker&#xff08;略&#xff09; 根据系统选择对应版本…

T-SQL游标的使用

一.建表 INSERT INTO cloud VALUES( 你 ) INSERT INTO cloud VALUES( 一会看我 ) INSERT INTO cloud VALUES( 一会看云 ) INSERT INTO cloud VALUES( 我觉得 ) INSERT INTO cloud VALUES( 你看我时很远 ) INSERT INTO cloud VALUES( 你看云时很近 ) 二.建立游标 1.游标的一般格…

微软Office Plus吊打WPS Office?不一定,WPS未来被它“拿捏”了

微软Office Plus吊打WPS Office&#xff1f; 微软的Office是一款非常强大的软件。不仅仅在办公领域中能给我们带来便利&#xff0c;在娱乐和生活的各个方面的管理也能带来很多便利。 当然&#xff0c;作为国产办公软件的排头兵WPS与微软Office的抗衡已经有长达30多年&#xf…

数据库sql语句(经典)

例题&#xff1a; 先来讲讲not in 和not exists的区别&#xff0c;再开始今天的例题&#xff08;和in&#xff0c;exists相反&#xff09; not in内外表做笛卡尔积&#xff0c;然后按照条件查询&#xff0c;没有用到索引 not exists是对外表进行循环&#xff0c;每次循环再对内…

从中国制造到中国智造,大眼橙投影仪的进阶之路

刚过去的5月10日是中国品牌日&#xff0c;在这一天各级电视台、广播电台以及平面、网络等媒体&#xff0c;都会安排重要版面来讲中国品牌故事。近日&#xff0c;笔者在与一些品牌的接触中&#xff0c;对大眼橙这个品牌印象颇深&#xff0c;大眼橙是智能投影行业的头部品牌&…

详解:函数栈帧的创建与销毁

函数栈帧的创建与销毁 前期问题函数栈帧定义寄存器的种类与功能汇编指令的功能及含义图解main函数之前的调用调用main函数开辟函数栈帧main函数中创建临时变量并初始化为形式参数创建开辟空间Add函数开辟函数栈帧&#xff0c;创建变量并进行运算释放Add函数栈帧 前期问题解答 铁…

STM32F4的输出比较极性和PWM1,PWM2的关系

PWM 输出比较通道 在这里以通用定时器的通道1作为介绍。 如图&#xff0c;左边就是CNT计数器和CCR1第一路的捕获/比较寄存器&#xff0c;它俩进行比较&#xff0c;当CNT>CCR1, 或者CNTCCR1时&#xff0c;就会给输出模式控制器传送一个信号&#xff0c;然后输出模式控制器就…

基于TextCNN、LSTM与Transformer模型的疫情微博情绪分类

基于TextCNN、LSTM与Transformer模型的疫情微博情绪分类 任务概述 微博情绪分类任务旨在识别微博中蕴含的情绪&#xff0c;输入是一条微博&#xff0c;输出是该微博所蕴含的情绪类别。在本次任务中&#xff0c;我们将微博按照其蕴含的情绪分为以下六个类别之一&#xff1a;积…

Docker部署nacos2.1版本集群

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称&#xff0c;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服…

spring发送qq邮件 + 模板引擎

文章目录 学习链接邮箱配置开启qq邮箱服务相关配置文件 freemarker模板引擎引入依赖配置freemarker编写模板registerTpl.ftl 发送带内嵌图片的邮件 附件效果 学习链接 java邮件发送 Java实现邮件发送 springboot发送QQ邮件&#xff08;最简单方式&#xff09; 刘java-Java使用…

css - 盒子水平垂直居中的几种方式

前端盒子水平垂直居中的几种方式 实现效果图如下&#xff1a; 首先是父元素的基本样式&#xff1a; .container {width: 600px;height: 600px;border: 1px solid red;background-color: antiquewhite;margin: 0 auto;/* 父盒子开启相对定位 */position: relative;}1&#xf…

【Linux】Linux入门学习之常用命令三

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…