SAM图像分割,实操应用,详细案例(点操作)——进阶

前言:

1、SAM单个输入点对应单个图像操作:

SAM图像分割,实操应用,详细案例(点操作)-CSDN博客

2、本文主旨在于“将SAM的点操作,融入到视频图像处理中”:

        主要以眼动仪中采集的具体场景下的眼坐标位置作为SAM中的点操作的点进行输入。以原视频作为图像,每个坐标点与该帧图像一一对应,进行单图片单坐标点处理,最后将结果图像压缩为视频进行输出。

内容:

1、新手可先阅读前言部分的1部分文章,便可知基本的单图操作。

2、主程序输入与输出

输入:原视频(session.mp4) ,对应的注视坐标点(gaze.xlsx)

输出:分割后的结果视频(myResultVideoTest.mp4)

①  重点函数 show_mask(image, mask):

# 输入:原图像image,与掩码mask。 输出: image + mask 的结果图像
def show_mask(image, mask):

    color = np.array([ 235, 251, 134])
    h, w = mask.shape[-2:]
    imageResult = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    for i in range(0, h ):
        for j in range(0, w ):
            if 0 not in imageResult[i][j]:
                image[i][j] = [ 235, 251, 134]
    return image

传入单个图片和单个图片对应的mask,可直接返回image + mask的最终结果图。

②  文件读取与变量定义:

sam_checkpoint = "C:\\Users\\MelonZhou\\Desktop\\PythonCode\\MindLink_SAM\\sam_vit_h_4b8939.pth"  # 定义模型路径
model_type = "vit_h"  # 定义模型类型
device = "cuda"  # "cpu"  or  "cuda"
sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device = device)  # 定义模型参数
predictor = SamPredictor(sam)  # 调用预测模型



df = pd.read_excel("gaze.xlsx", sheet_name = "Sheet1") # 读取视频图像对应的坐标点(x,y)
numpy_array = df.to_numpy() # 将excel转为矩阵格式
myArrayList = numpy_array

video_path = "session.mp4" # 原视频文件路径
cap = cv2.VideoCapture(video_path) # 创建视频读取对象
frame_width = int(cap.get(3)) # session.mp4 视频图像的宽(1920)
frame_height = int(cap.get(4)) # session.mp4 视频图像的宽(1080)

# 定义编解码器并创建视频写入对象
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
video = cv2.VideoWriter('myResultVideoTest.mp4', fourcc, 30, (frame_width, frame_height),True)

读取excel中每一帧图像对应的注视坐标点,文章中用到了pandas库。

读入视频,并拆解视频为每帧图像,文章中用到了cv2.VideoCapture()等视频读取功能函数。

要把处理后的图片写成视频,所以文章中用到了 cv2.VideoWriter()等视频封装功能函数。

③  解析视频为单帧图片,循环调用SAM模型进行识别分割:

while cap.isOpened():
    start_time = time.time()
    ret, frame = cap.read()
    if not ret:
        break
    image = frame  # 读取的图像以NumPy数组的形式存储在变量image中
    image1 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 将图像从BGR颜色空间转换为RGB颜色空间,还原图片色彩(图像处理库所认同的格式)

    predictor.set_image(image1)
    input_point = np.array([myArrayList[listIndex]])
    input_label = np.array([1])  # 点所对应的标签
    masks, scores, logit = predictor.predict(
        point_coords=input_point,
        point_labels=input_label,
        multimask_output=True,  # 为False时,它将返回一个掩码
    )

    imageResult = show_mask(image, masks[1])
    video.write(imageResult)
    plt.show()

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    listIndex += 1
    end_time = time.time()
    execution_time = end_time - start_time  # 计算运行时间
    print("Numbers", listIndex, ":  ", scores,"   ",execution_time,"s")

这一块内容是完全继承前言1中内容,所以建议读者可以先理解前言1中的文章内容。

3、总代码:

import time
import cv2
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from segment_anything import sam_model_registry, SamPredictor
import warnings
warnings.filterwarnings("ignore")

# 输入:原图像image,与掩码mask。 输出: image + mask 的结果图像
def show_mask(image, mask):

    color = np.array([ 235, 251, 134])
    h, w = mask.shape[-2:]
    imageResult = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    for i in range(0, h ):
        for j in range(0, w ):
            if 0 not in imageResult[i][j]:
                image[i][j] = [ 235, 251, 134]
    return image


sam_checkpoint = "C:\\Users\\MelonZhou\\Desktop\\PythonCode\\MindLink_SAM\\sam_vit_h_4b8939.pth"  # 定义模型路径
model_type = "vit_h"  # 定义模型类型
device = "cuda"  # "cpu"  or  "cuda"
sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device = device)  # 定义模型参数
predictor = SamPredictor(sam)  # 调用预测模型



df = pd.read_excel("gaze.xlsx", sheet_name = "Sheet1") # 读取视频图像对应的坐标点(x,y)
numpy_array = df.to_numpy() # 将excel转为矩阵格式
myArrayList = numpy_array

video_path = "session.mp4" # 原视频文件路径
cap = cv2.VideoCapture(video_path) # 创建视频读取对象
frame_width = int(cap.get(3)) # session.mp4 视频图像的宽(1920)
frame_height = int(cap.get(4)) # session.mp4 视频图像的宽(1080)

# 定义编解码器并创建视频写入对象
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
video = cv2.VideoWriter('myResultVideoTest.mp4', fourcc, 30, (frame_width, frame_height),True)

number = 1
listIndex = 0
# 逐帧读取视频
while cap.isOpened():
    start_time = time.time()
    ret, frame = cap.read()
    if not ret:
        break
    image = frame  # 读取的图像以NumPy数组的形式存储在变量image中
    image1 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 将图像从BGR颜色空间转换为RGB颜色空间,还原图片色彩(图像处理库所认同的格式)

    predictor.set_image(image1)
    input_point = np.array([myArrayList[listIndex]])
    input_label = np.array([1])  # 点所对应的标签
    masks, scores, logit = predictor.predict(
        point_coords=input_point,
        point_labels=input_label,
        multimask_output=True,  # 为False时,它将返回一个掩码
    )

    imageResult = show_mask(image, masks[1])
    video.write(imageResult)
    plt.show()

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    listIndex += 1
    end_time = time.time()
    execution_time = end_time - start_time  # 计算运行时间
    print("Numbers", listIndex, ":  ", scores,"   ",execution_time,"s")

# 释放资源
cap.release()
video.release()
cv2.destroyAllWindows()

4、结果展示:

眼动仪视频如下:

CarsDatas

输入视频与数出视频:

session.mp4

myResultVideoTest

总结:

        目前因为原始数据gaze.xlsx未经详细处理,也未深度优化其具体代码,所以在与对应点和对应帧的图像分割上还存在小问题。但具体思路笔者在这里给出,学者们可以自己再度深化其内容。

gaze.xlsx:具体的每帧图像对应的输入坐标点(x,y)

gaze_data.csv:原生的眼动仪导出的注视坐标点数据(本文章未用到该文件)

main.py:主程序

myResultVideoTest.mp4:最后生成的结果视频

sam_vit_h_4b8939.pth:SAM模型参数(有本地获取联网自动获取两种方式,详看前言1)

session.mp4:原始的视频

附录:

gaze.xlsx文件内容截图:

### SAM2 多提示分割功能概述 SAM(Segment Anything Model)的核心能力之一在于其能够基于多种类型的提示信息完成图像分割任务。这些提示信息可以是框、或是文本等形式[^1]。当提到“多提示”的时候,意味着用户可以在目标对象的不同位置提供多个作为输入提示,从而帮助模型更精确地定位和分割目标。 #### 多提示的工作原理 在 SAM 的设计中,“”作为一种提示形式被用来指示感兴趣的区域或背景区域的位置。对于单个的情况,它可以表示目标中心或其他显著特征所在之处;而对于多个,则允许进一步细化指定范围内的细节。例如,在复杂场景下,仅仅依靠单一击可能不足以让算法理解用户的意图,这时便可通过增加额外的正面(属于目标的部分)或负面(不属于目标的部分)标记来增强指导效果[^2]。 以下是SAM2 中多提示分割的主要技术要: 1. **正负样本区分**: 用户可以通过鼠标左键添加正面样例(即希望保留下来的前景部分),而右键则用于定义反面样例(即应排除在外的背景成分)。这种机制使得即使面对遮挡物或者相似颜色干扰的情况下也能获得较为理想的输出结果。 2. **API 调用说明**: 利用 Python 接口调用 `predict` 方法时传入参数列表中的 points 和 labels 字段分别存储上述两类坐标及其对应标签值 (0 表示背景, 1 表示前景)[^3]. 下面给出一段简单的代码演示如何利用 SAM 进行基于多提示的例化操作: ```python from segment_anything import sam_model_registry, SamPredictor import cv2 import numpy as np def show_mask(mask, ax, random_color=False): if random_color: color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0) else: 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) image_path = 'example.jpg' image = cv2.imread(image_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 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) predictor = SamPredictor(sam) predictor.set_image(image) input_point = np.array([[500, 375], [100, 100]]) # Example of two input points. input_label = np.array([1, 0]) masks, scores, logits = predictor.predict( point_coords=input_point, point_labels=input_label, multimask_output=True, ) for i, mask in enumerate(masks): plt.figure(figsize=(10,10)) plt.imshow(image) show_mask(mask, plt.gca()) plt.axis('off') plt.show() ``` 此脚本展示了加载预训练权重文件以及设置待分析影像之后,怎样向预测器传递一组包含两个不同性质坐标的数组,并最终获取到若干候选蒙版的过程[^4]。 ### 注意事项 尽管当前版本已经具备相当程度上的灵活性与便捷度,但在应用过程中仍需注意某些特定场合下的局限性问题,比如极端情况下可能出现误判现象等状况的发生概率相对较高一些。因此建议开发者们根据各自项目需求适当调整阈值设定或者是引入更多辅助手段共同作用于决策环节之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值