补充软著核心功能图文素材

- 重拍创建多边形、AI自动推理、AI智能分割的高清截图与分段视频素材。

- 更新软著说明书,补充多边形绘制、传播范围、传播执行、AI点选分割和候选结果的图文说明。

- 清理说明书中的重复图片引用,修复不存在的工作区截图路径。

- 更新功能验证与素材清单,登记新增截图、MP4/WebM 视频和验证说明。

- 增加线上核心功能素材录制脚本,便于后续重新生成软著截图与视频。
This commit is contained in:
2026-05-08 02:12:24 +08:00
parent d369674906
commit abd8c73812
17 changed files with 239 additions and 34 deletions

View File

@@ -0,0 +1,189 @@
import { chromium } from 'playwright';
import fs from 'node:fs/promises';
import path from 'node:path';
const BASE_URL = process.env.SEG_DEMO_URL || 'https://seg.huijutec.cn/';
const USERNAME = process.env.SEG_DEMO_USER || 'admin';
const PASSWORD = process.env.SEG_DEMO_PASSWORD || '123456';
const OUT_ROOT = process.env.SEG_DEMO_OUT_DIR || path.resolve('新撰写软著文档');
const IMAGE_DIR = path.join(OUT_ROOT, 'images');
const VIDEO_DIR = path.join(OUT_ROOT, '系统使用视频');
const viewport = { width: 1920, height: 1080 };
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function ensureDirs() {
await fs.mkdir(IMAGE_DIR, { recursive: true });
await fs.mkdir(VIDEO_DIR, { recursive: true });
}
async function login(page) {
await page.goto(BASE_URL, { waitUntil: 'networkidle', timeout: 60000 });
await page.locator('input[type="text"]').first().fill(USERNAME);
await page.locator('input[type="password"]').first().fill(PASSWORD);
await page.getByRole('button', { name: /安全登录|登录/ }).click();
await page.waitForLoadState('networkidle').catch(() => {});
await sleep(1800);
}
async function shot(page, filename) {
await page.screenshot({
path: path.join(IMAGE_DIR, filename),
fullPage: false,
animations: 'disabled',
});
console.log(`screenshot ${filename}`);
}
async function clickTitle(page, title, settle = 1000) {
await page.getByTitle(title).first().click();
await page.waitForLoadState('networkidle').catch(() => {});
await sleep(settle);
}
async function openWorkspace(page) {
await clickTitle(page, '项目库', 800);
await page.getByText('演视LC视频序列').first().click();
await page.waitForLoadState('networkidle').catch(() => {});
await sleep(2200);
}
async function canvasBox(page) {
const canvas = page.locator('.konvajs-content canvas').first();
const box = await canvas.boundingBox();
if (!box) throw new Error('Canvas is not visible.');
return box;
}
async function drawPolygonDraft(page) {
await page.getByRole('button', { name: /肿瘤\/结节|胆囊/ }).first().click().catch(() => {});
await page.getByTitle('创建多边形 (P)').click();
await sleep(400);
const box = await canvasBox(page);
const points = [
[box.x + box.width * 0.38, box.y + box.height * 0.38],
[box.x + box.width * 0.57, box.y + box.height * 0.40],
[box.x + box.width * 0.52, box.y + box.height * 0.60],
[box.x + box.width * 0.35, box.y + box.height * 0.55],
];
for (const [x, y] of points) {
await page.mouse.click(x, y);
await sleep(250);
}
}
async function completePolygon(page) {
await page.keyboard.press('Enter');
await sleep(1000);
}
async function captureCoreScreenshots() {
const browser = await chromium.launch({ headless: true, args: ['--window-size=1920,1080'] });
const context = await browser.newContext({ viewport, deviceScaleFactor: 1 });
const page = await context.newPage();
await login(page);
await openWorkspace(page);
await shot(page, '24-workspace-current-frame-timeline.png');
await drawPolygonDraft(page);
await shot(page, '25-create-polygon-vertices.png');
await completePolygon(page);
await shot(page, '26-create-polygon-completed.png');
await page.getByTitle('AI自动推理').click();
await sleep(800);
await page.getByLabel('传播起始帧').fill('1').catch(() => {});
await page.getByLabel('传播结束帧').fill('3').catch(() => {});
await shot(page, '27-ai-auto-inference-range.png');
await page.getByRole('button', { name: '开始传播' }).click();
await sleep(1800);
await shot(page, '28-ai-auto-inference-running.png');
await page.waitForFunction(() => document.body.innerText.includes('已自动传播') || document.body.innerText.includes('没有生成新'), null, { timeout: 90000 }).catch(() => {});
await sleep(1000);
await shot(page, '29-ai-auto-inference-completed.png');
await clickTitle(page, 'AI智能分割', 1800);
await page.getByRole('button', { name: '正向选点' }).click();
const box = await canvasBox(page);
await page.mouse.click(box.x + box.width * 0.48, box.y + box.height * 0.48);
await sleep(700);
await shot(page, '30-ai-segmentation-positive-point.png');
await page.getByRole('button', { name: '执行高精度语义分割' }).click();
await page.waitForFunction(() => {
const text = document.body.innerText;
return text.includes('AI Mask') || text.includes('候选') || text.includes('推送至工作区编辑');
}, null, { timeout: 90000 }).catch(() => {});
await sleep(1200);
await shot(page, '31-ai-segmentation-result.png');
await browser.close();
}
async function recordVideo(name, action) {
const browser = await chromium.launch({ headless: true, args: ['--window-size=1920,1080'] });
const context = await browser.newContext({
viewport,
deviceScaleFactor: 1,
recordVideo: { dir: VIDEO_DIR, size: viewport },
});
const page = await context.newPage();
await action(page);
await sleep(800);
const video = page.video();
await context.close();
await browser.close();
const videoPath = await video?.path();
if (!videoPath) return;
const finalPath = path.join(VIDEO_DIR, `${name}.webm`);
await fs.rm(finalPath, { force: true });
await fs.rename(videoPath, finalPath);
console.log(`video ${path.basename(finalPath)}`);
}
async function captureVideos() {
await recordVideo('05-创建多边形标注演示', async (page) => {
await login(page);
await openWorkspace(page);
await drawPolygonDraft(page);
await sleep(900);
await completePolygon(page);
await sleep(1600);
});
await recordVideo('06-AI自动推理传播演示', async (page) => {
await login(page);
await openWorkspace(page);
await drawPolygonDraft(page);
await completePolygon(page);
await page.getByTitle('AI自动推理').click();
await sleep(900);
await page.getByLabel('传播起始帧').fill('1').catch(() => {});
await page.getByLabel('传播结束帧').fill('3').catch(() => {});
await sleep(900);
await page.getByRole('button', { name: '开始传播' }).click();
await sleep(5000);
});
await recordVideo('07-AI智能分割点选推理演示', async (page) => {
await login(page);
await openWorkspace(page);
await clickTitle(page, 'AI智能分割', 1800);
await page.getByRole('button', { name: '正向选点' }).click();
const box = await canvasBox(page);
await page.mouse.click(box.x + box.width * 0.48, box.y + box.height * 0.48);
await sleep(1000);
await page.getByRole('button', { name: '执行高精度语义分割' }).click();
await sleep(5000);
});
}
async function main() {
await ensureDirs();
await captureCoreScreenshots();
await captureVideos();
}
main().catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -32,12 +32,10 @@
用户登录后系统默认进入“总体概况”页面。该页面用于查看系统全局数据监控情况包括项目总数、处理任务数量、已保存标注数量、系统负载等摘要信息。页面中还展示后台任务列表与活动记录用户可了解视频解析、DICOM 解析、自动推理等任务的处理进度。
![](images/02-dashboard.png)
![](images/04-dashboard-tasks.png)
在任务列表中,用户可查看任务名称、处理进度、当前状态和更新时间。对于正在执行的任务,可根据系统提供的操作按钮进行取消处理;对于失败或已取消的任务,可根据需要重新执行。任务执行过程中,系统会在界面中持续更新进度提示,便于用户掌握当前处理状态。
![](images/04-dashboard-tasks.png)
## 3.2 项目库管理
单击左侧“项目库”按钮后系统进入视频与连续帧项目库页面。该页面用于管理多媒体项目支持导入视频文件、DICOM 序列文件,并对已有项目进行查看、重命名、复制、删除和进入工作区等操作。
@@ -54,8 +52,6 @@
选择“导入DICOM序列”时用户可批量选择 DICOM 文件。系统会按照文件名自然顺序读取序列避免切片顺序错位。上传及解析过程中项目库会显示导入进度、文件数量和处理状态。解析完成后DICOM 项目可与普通帧序列项目一样进入分割工作区进行标注。
![](images/06-import-media-options.png)
项目卡片中提供项目名称编辑入口。用户单击编辑按钮后,可修改项目名称,确认后系统更新项目列表中的显示名称。项目卡片旁还提供复制功能,用户可选择“新项目重置”或“全内容复制”;前者复制项目媒体和帧序列但不复制标注,后者复制项目内容及已有标注信息。删除项目时,系统会弹出确认提示,用户确认后系统移除该项目。
![](images/07-project-copy-dialog.png)
@@ -66,49 +62,61 @@
在项目库中选择项目后系统进入“分割工作区”。分割工作区中部为影像或视频帧显示区域左侧为标注工具栏右侧为语义分类树底部为帧序列时间轴。用户可在此完成帧浏览、手工标注、AI 自动推理、GT Mask 导入、标注保存与结果导出等工作。
![](images/09-workspace-main.png)
![](images/24-workspace-current-frame-timeline.png)
用户可通过底部时间轴切换当前帧也可使用播放控制按钮浏览连续帧。右下角显示当前帧序号及总帧数。若某一帧已经存在人工标注、AI 标注或自动传播结果,时间轴会用不同颜色进行提示,便于用户快速定位已处理帧。
![](images/09-workspace-main.png)
左侧工具栏提供多边形、矩形、圆形、画笔、橡皮擦、区域合并、重叠区域去除、删除遮罩、清空遮罩、导入 GT Mask 和 AI 智能分割等工具。用户在右侧语义分类树中选择分类后,可使用绘制工具在当前图像上创建新的标注区域;若当前已有选中遮罩,绘制内容可并入当前选中区域。
![](images/10-workspace-tools.png)
使用多边形工具时,用户可依次单击图像边界点形成标注轮廓,完成闭合后系统生成遮罩。使用矩形或圆形工具时,用户可拖拽生成规则区域。使用画笔工具时,用户可调节画笔大小并在图像上连续涂画;使用橡皮擦工具时,用户可调节橡皮擦大小并对选中遮罩进行擦除修正
使用“创建多边形工具时,用户可依次单击图像边界点形成标注轮廓。系统会在图像上显示已放置顶点和临时边界线,帮助用户确认轮廓位置
![](images/11-workspace-draw-mask.png)
![](images/25-create-polygon-vertices.png)
多边形闭合后,系统生成遮罩并自动选中该遮罩,界面显示可编辑边界点。用户可继续拖动顶点微调区域,也可切换语义分类树修改该遮罩所属类别。使用矩形、圆形或画笔工具时,系统同样会在当前帧生成可编辑遮罩;画笔工具可调节笔刷大小,橡皮擦工具可对选中遮罩进行局部擦除。
![](images/26-create-polygon-completed.png)
[查看分段演示视频:创建多边形标注](系统使用视频/05-创建多边形标注演示.mp4)
当需要处理多个相邻或相关区域时,用户可选择“区域合并”功能,将多个遮罩合并为同一区域;选择“重叠区域去除”功能,可对重叠遮罩进行裁决处理。对于传播产生的连续帧遮罩,系统会提示用户选择操作范围,包括当前帧、指定范围帧或所有传播帧。
![](images/12-workspace-auto-propagate-range.png)
用户可通过“DEL”按钮或键盘删除选中遮罩也可通过“清空遮罩”按钮清除当前帧或传播范围内的遮罩。若选择的范围包含人工标注帧系统会提示用户确认是否同步处理人工标注内容避免误删重要数据。右侧“语义分类树”用于管理当前项目的标注类别没有选中任何遮罩时单击分类仅改变后续新建遮罩的默认分类已选中遮罩时则用于修改当前遮罩分类。
用户可通过“DEL”按钮或键盘删除选中遮罩也可通过“清空遮罩”按钮清除当前帧或传播范围内的遮罩。若选择的范围包含人工标注帧系统会提示用户确认是否同步处理人工标注内容避免误删重要数据。
## 3.4 AI 自动推理
![](images/12-workspace-auto-propagate-range.png)
在分割工作区中用户可单击左侧工具栏的“AI自动推理”按钮。系统进入传播范围选择状态并在顶部显示传播权重、起始帧、结束帧、向前传播帧数和向后传播帧数。用户可在时间轴上拖拽选择范围也可直接填写帧号。
右侧“语义分类树”用于管理当前项目的标注类别。用户单击分类项后,后续新建遮罩将应用该语义分类。若没有选中任何遮罩,单击分类仅改变后续新建遮罩的默认分类;若已选中遮罩,单击分类可修改该遮罩的语义类别。
![](images/27-ai-auto-inference-range.png)
![](images/10-workspace-tools.png)
确认范围后,用户单击“开始传播”按钮。系统以当前帧已有遮罩为参考,在指定范围内自动生成连续帧分割结果。传播期间,界面顶部显示当前处理状态,用户可继续观察时间轴与当前帧区域。
## 3.4 AI 智能分割
![](images/28-ai-auto-inference-running.png)
传播完成后,系统会保存生成结果,并在底部时间轴中用自动传播颜色标识相关帧段。用户可切换到传播后的帧检查遮罩位置,必要时继续使用多边形调整、画笔、橡皮擦或语义分类树进行修正。
![](images/29-ai-auto-inference-completed.png)
[查看分段演示视频AI自动推理传播](系统使用视频/06-AI自动推理传播演示.mp4)
## 3.5 AI 智能分割
单击左侧导航栏中的“AI智能分割”按钮系统进入模型端推理可视化界面。用户可选择 SAM 2.1 Tiny、Small、Base+、Large 等模型权重。系统会显示当前模型是否可用以及设备状态,若模型不可用,对应选项将不可执行。
![](images/15-ai-page.png)
用户可在图像中添加正向点、反向点或边界框提示,系统根据提示生成候选分割结果。生成结果后,用户可查看候选遮罩边界,并可继续添加提示点进行细化。确认结果后,用户可将分割结果推送至分割工作区,并在工作区中继续进行语义分类、顶点调整和保存
用户可在图像中添加正向点、反向点或边界框提示,系统根据提示生成候选分割结果。添加正向点时,用户应单击目标区域内部;添加反向点时,用户应单击希望排除的区域。提示点会显示在图像上,用户可根据需要删除提示点后重新选择
![](images/16-ai-prompt-tools.png)
![](images/30-ai-segmentation-positive-point.png)
在分割工作区中用户也可单击左侧工具栏的“AI自动推理”按钮选择需要传播的帧范围并单击“开始传播”。系统会以当前帧已有遮罩为参考在指定范围内自动生成连续帧分割结果。传播期间系统在顶部显示当前处理进度完成后时间轴中会显示自动传播产生的帧段
单击“执行高精度语义分割”后,系统生成候选遮罩并叠加显示在图像上。用户可查看候选遮罩边界,并可继续添加提示点进行细化。确认结果后,用户可将分割结果推送至分割工作区,并在工作区中继续进行语义分类、顶点调整和保存
![](images/12-workspace-auto-propagate-range.png)
![](images/31-ai-segmentation-result.png)
[查看分段演示视频AI推理与结果导出](系统使用视频/03-AI推理与结果导出演示.mp4)
[查看分段演示视频AI智能分割点选推理](系统使用视频/07-AI智能分割点选推理演示.mp4)
## 3.5 GT Mask 导入与结果预览
## 3.6 GT Mask 导入与结果预览
在分割工作区中,用户可单击“导入 GT Mask”按钮选择本地 GT Mask 图片。系统会检查图片是否符合要求GT 图片应为灰度图,或 RGB 三通道像素值一致的图像,像素值代表对应 maskid0 代表背景。若图片尺寸与当前帧不同,系统会自动按当前帧尺寸适配。
@@ -116,9 +124,7 @@
导入后,系统显示导入结果预览。若图片中存在当前模板未定义的类别,系统会提示用户选择处理方式:可舍弃未知类别,也可将其作为“待分类”遮罩导入,后续再重新命名。若图片不符合要求或没有非背景区域,系统会显示错误提示并拒绝导入。
![](images/14-gt-mask-import-preview.png)
## 3.6 分割结果导出
## 3.7 分割结果导出
完成标注后,用户可在分割工作区单击“分割结果导出”按钮。系统弹出导出配置界面,用户可选择导出范围,包括当前图片、特定范围帧或整体视频。系统默认导出当前帧结果,用户也可在时间轴上拖拽选择导出范围。
@@ -126,9 +132,7 @@
导出内容可包括分开二值 mask、GT_label 黑白图、Pro_label 彩色图、Mix_label 原图叠加图及标注数据文件。用户确认后,系统生成压缩包并下载到本地。导出的 GT_label 文件中,像素值与语义分类的 maskid 对应;“待分类”与背景均以 0 值表示。
![](images/13-workspace-export-dialog.png)
## 3.7 模板库管理
## 3.8 模板库管理
单击左侧“模板库”按钮,系统进入生效中模板架构清单页面。模板库用于管理语义分类模板,系统内置腹腔镜胆囊切除术、头颈部 CT 分割等默认模板。用户可查看模板名称、描述和分类树,并可复制模板形成新的可编辑模板。
@@ -144,17 +148,15 @@
[查看分段演示视频:模板库与用户管理](系统使用视频/04-模板库与用户管理演示.mp4)
## 3.8 用户管理与审计
## 3.9 用户管理与审计
管理员可单击左侧“用户管理”进入用户管理后台。该页面显示当前用户列表、用户角色、启用状态和操作按钮。管理员可创建标注员账号、修改用户密码、停用或启用用户,也可删除不再使用的账号。
![](images/20-user-admin.png)
用户管理页面还显示安全审计日志。管理员可查看登录、用户管理、恢复演示环境等操作记录,用于追踪系统使用情况。若需要恢复演示环境,管理员可单击“恢复演示出厂设置”,并按界面提示输入确认文本。系统完成恢复后,仅保留默认管理员、演示视频项目、演示 DICOM 项目和默认模板数据。
![](images/22-audit-reset-dialog.png)
## 3.9 退出系统
## 3.10 退出系统
用户完成工作后,可单击左下角当前用户图标旁的退出按钮。系统清除当前登录状态并返回登录界面。再次使用时,用户需重新输入账号和密码登录系统。

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 KiB

View File

@@ -1,7 +1,7 @@
# 功能验证与素材清单
验证地址https://seg.huijutec.cn/
验证时间2026/5/8 01:38:02
验证时间2026/5/8 02:07:00
## 截图文件
- images/01-login.png系统登录界面图
@@ -27,19 +27,33 @@
- images/21-user-create-dialog.png新增标注员账号界面图
- images/22-audit-reset-dialog.png审计日志和恢复演示出厂设置确认界面图
- images/23-logout.png退出登录按钮和返回登录界面图
- images/24-workspace-current-frame-timeline.png分割工作区当前帧和帧序列时间轴界面图
- images/25-create-polygon-vertices.png创建多边形过程中顶点和临时轮廓界面图
- images/26-create-polygon-completed.png多边形闭合后遮罩和可编辑边界点界面图
- images/27-ai-auto-inference-range.pngAI自动推理传播范围和权重选择界面图
- images/28-ai-auto-inference-running.pngAI自动推理任务运行状态界面图
- images/29-ai-auto-inference-completed.pngAI自动推理完成后传播帧段标识界面图
- images/30-ai-segmentation-positive-point.pngAI智能分割正向点提示界面图
- images/31-ai-segmentation-result.pngAI智能分割候选结果叠加界面图
## 分段视频
- 系统使用视频/01-登录与总体概况演示.mp4
- 系统使用视频/02-项目库与分割工作区演示.mp4
- 系统使用视频/03-AI推理与结果导出演示.mp4
- 系统使用视频/04-模板库与用户管理演示.mp4
- 系统使用视频/05-创建多边形标注演示.mp4
- 系统使用视频/06-AI自动推理传播演示.mp4
- 系统使用视频/07-AI智能分割点选推理演示.mp4
- 系统使用视频/01-登录与总体概况演示.webm
- 系统使用视频/02-项目库与分割工作区演示.webm
- 系统使用视频/03-AI推理与结果导出演示.webm
- 系统使用视频/04-模板库与用户管理演示.webm
- 系统使用视频/05-创建多边形标注演示.webm
- 系统使用视频/06-AI自动推理传播演示.webm
- 系统使用视频/07-AI智能分割点选推理演示.webm
## 验证说明
本次验证以管理员账号进入线上系统逐项检查登录、总体概况、项目库、分割工作区、AI 智能分割、AI 自动推理入口、GT Mask 导入预览、分割结果导出、模板库、用户管理、审计日志和退出登录等说明书涉及功能。删除项目、恢复演示出厂设置、生成帧确认、导出下载确认等可能改变演示环境或产生下载文件的危险提交动作仅验证入口与确认界面,不执行最终提交。
本次验证以管理员账号进入线上系统,逐项检查登录、总体概况、项目库、分割工作区、创建多边形标注、AI 智能分割点选推理、AI 自动推理传播、GT Mask 导入预览、分割结果导出、模板库、用户管理、审计日志和退出登录等说明书涉及功能。删除项目、恢复演示出厂设置、生成帧确认、导出下载确认等可能改变演示环境或产生下载文件的危险提交动作仅验证入口与确认界面,不执行最终提交。说明书已调整为每个截图文件只引用一次,避免同一界面图重复出现在多个功能段落。
## 自动化测试补充