SAMLabeler-MNN 项目使用与编译问题解决

项目链接:SAMLabeler-MNN

个人开源主页:地址

本文档面向需要在 Linux 上编译、运行和使用 SAMLabeler-MNN 的开发者与标注

人员。内容包括环境准备、MNN 路径配置、编译与测试、标注流程、项目输出,以及常见

配置、链接和运行问题的排查方法。

本文命令默认在项目根目录执行。当前项目根目录示例为:

text 复制代码
/path/to/SAMLabeler-MNN

为便于迁移,正文优先使用相对路径和 /path/to/... 占位符。

1. 项目简介

SAMLabeler-MNN 是一个基于 C++11、Qt 5、OpenCV、MNN 和 MobileSAM vit_t

本地半自动化交互标注工具,主要用于制作语义分割和实例分割标注。

当前主要能力:

  • 正点、负点和矩形框 Prompt;
  • 多类别及自定义显示颜色;
  • 同图、同类别下的顺序实例标注;
  • 已确认实例的重新编辑和删除;
  • 从模型 mask 转换为 Polygon 后精调边界;
  • 语义 mask、实例 mask、类别映射和可恢复编辑状态保存;
  • 独立的 C++/OpenCV/MNN 后端和兼容 OpenCV 示例。

当前没有实现 Pascal VOC、COCO、YOLO Segmentation 等通用数据集格式的直接导入

或导出。项目目录中的 PNG、JSON 和状态文件是 SAMLabeler-MNN 当前的项目格式。

2. 目录和主要目标

常用目录:

text 复制代码
SAMLabeler-MNN/
├── app/                     # Qt 界面
├── include/                 # 公共 C++ 头文件
├── src/                     # MNN 后端和标注业务实现
├── tests/                   # 自动测试
├── examples/                # 原 OpenCV 交互示例
├── data/models/             # 默认 MobileSAM MNN 模型
├── demo/                    # README 演示图片
├── docs/                    # 使用文档
└── CMakeLists.txt

CMake 主要目标:

目标 用途
SAMLabeler-MNN Qt 标注应用程序
MobileSamCore MobileSAM/MNN 后端静态库
AnnotationDomain 标注业务静态库
InteractiveSegmenter MobileSamCore 的兼容别名
TestInteractiveSegmenter OpenCV 单图交互示例
TestMobileSamBackend MobileSAM 后端真实模型测试
TestAnnotationSession 标注项目和持久化测试

3. 编译依赖

最低或当前约束:

依赖 要求
C++ 编译器 支持 C++11
CMake 3.10 或更高
Ninja 推荐;也可使用其他 CMake 生成器
Qt 5.15,组件为 Core、Gui、Widgets
OpenCV 4.x,组件为 core、imgproc、imgcodecs、highgui
MNN 兼容 3.3.x 的头文件和共享库 libMNN.so
模型 MobileSAM vit_t encoder 和 decoder 的 MNN 文件

3.1 环境检查

bash 复制代码
cmake --version
ninja --version
c++ --version
pkg-config --modversion opencv4
pkg-config --modversion Qt5Core

pkg-config 查不到 Qt 并不一定表示 Qt 不存在;CMake 也可能通过

Qt5Config.cmake 找到它。最终应以 CMake 配置结果为准。

检查默认模型:

bash 复制代码
test -f data/models/mobile_sam_encoder.mnn && echo "encoder OK"
test -f data/models/mobile_sam_decoder.mnn && echo "decoder OK"

检查外部 MNN:

bash 复制代码
test -f /path/to/MNN/include/MNN/Interpreter.hpp && echo "MNN headers OK"
test -f /path/to/MNN/build/libMNN.so && echo "MNN library OK"

3.2 Ubuntu/Debian 依赖示例

以下命令仅是常见 Ubuntu/Debian 环境的参考,请先根据系统版本审核包名,再由用户

手动执行:

bash 复制代码
sudo apt update
sudo apt install build-essential cmake ninja-build pkg-config \
  qtbase5-dev libopencv-dev

MNN 不由本项目自动下载或编译。请准备与项目兼容的 MNN 源码头文件和已构建的

libMNN.so,然后通过 CMake 参数提供路径。

4. 配置和编译

4.1 推荐构建命令

进入项目根目录:

bash 复制代码
cd /home/panguofeng/pgf_ai_deploy/SAMLabeler-MNN

配置:

bash 复制代码
cmake -S . -B build-qt -G Ninja \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so

编译:

bash 复制代码
cmake --build build-qt

成功后应生成:

text 复制代码
build-qt/SAMLabeler-MNN
build-qt/TestInteractiveSegmenter
build-qt/TestMobileSamBackend
build-qt/TestAnnotationSession

只编译 Qt 应用:

bash 复制代码
cmake --build build-qt --target SAMLabeler-MNN

4.2 使用项目默认 MNN 路径

当前 CMakeLists.txt 的默认值是:

text 复制代码
MNN_ROOT=/home/panguofeng/project/MNN
MNN_LIBRARY=/home/panguofeng/project/MNN/build/libMNN.so

如果这两个路径在当前机器上有效,可以简化为:

bash 复制代码
cmake -S . -B build-qt -G Ninja
cmake --build build-qt

在其他机器上不应依赖这个开发者路径,应显式传入实际位置。

4.3 严格警告编译

建议开发或提交前在独立构建目录执行:

bash 复制代码
cmake -S . -B build-strict -G Ninja \
  -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic" \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so
cmake --build build-strict

独立目录可避免严格选项与日常构建缓存互相影响。

4.4 Debug 或 Release 构建

单配置生成器(如 Ninja)可使用:

bash 复制代码
cmake -S . -B build-release -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so
cmake --build build-release

调试时将 Release 改为 Debug

5. 运行程序

5.1 使用仓库内默认模型

程序默认从当前工作目录读取:

text 复制代码
data/models/mobile_sam_encoder.mnn
data/models/mobile_sam_decoder.mnn

因此应从项目根目录运行:

bash 复制代码
./build-qt/SAMLabeler-MNN

5.2 显式指定模型

bash 复制代码
./build-qt/SAMLabeler-MNN \
  /path/to/mobile_sam_encoder.mnn \
  /path/to/mobile_sam_decoder.mnn

必须同时提供 encoder 和 decoder。面向用户的正常启动形式只有:

text 复制代码
SAMLabeler-MNN
SAMLabeler-MNN <encoder.mnn> <decoder.mnn>

5.3 动态库搜索路径

Linux 构建会把配置时 MNN_LIBRARY 所在目录写入构建产物的 RUNPATH。可检查:

bash 复制代码
readelf -d build-qt/SAMLabeler-MNN | grep -E 'RPATH|RUNPATH'
ldd build-qt/SAMLabeler-MNN | grep -E 'MNN|not found'

如果移动了 MNN 库或二进制文件,可以重新配置构建,或临时指定:

bash 复制代码
export LD_LIBRARY_PATH=/path/to/MNN/build:${LD_LIBRARY_PATH}
./build-qt/SAMLabeler-MNN

6. 标注操作流程

6.1 选择目录

界面中的两个目录相互独立:

  • 选择图像文件夹:读取待标注图片,不把项目文件写入源图片目录;
  • 选择标注文件夹:加载或保存 SAMLabeler-MNN 项目。

支持大小写不敏感的 PNG、JPG/JPEG、BMP、TIF/TIFF。两个目录的选择顺序不受

限制。更换目录前如有未保存修改,程序会请求确认。

6.2 创建类别

  1. 点击"添加类别及颜色";
  2. 输入非空且不与现有类别重名的名称;
  3. 选择显示颜色;
  4. 可继续重命名、修改颜色或删除类别。

类别 ID 是稳定的正整数。删除类别会同时删除该类别在所有图片中的标注状态,操作前

应确认项目已正确备份或保存。

6.3 使用 Prompt 生成 mask

  • 正点 :标记目标内部,decoder label 为 1
  • 负点 :标记不属于目标的区域,decoder label 为 0
  • 矩形框 :拖动目标包围框,两个角分别使用 label 23

当前 decoder 使用固定 8 槽位输入:

  • 一个点占 1 个槽位;
  • 一个矩形框占 2 个槽位;
  • 容量不足时当前请求会被拒绝,不会覆盖已有 mask 和 feedback。

同一图片的不同类别、不同实例各自保存 Prompt、mask 和 decoder feedback,不会相互

复用编辑状态。

6.4 顺序实例标注

  1. 选择类别后编辑当前草稿实例;
  2. 用点或矩形框获得有效 mask;
  3. 点击"确认当前目标";
  4. 当前实例变为已确认,程序创建同类别的下一个空白实例;
  5. 重复操作,完成该类别的多个目标。

实例 ID 在单张图片内从 1 单调递增,0 表示背景,删除后的 ID 不复用。已确认实例

不能直接追加 Prompt;应先点击"重新编辑"。"重置当前实例"只清空当前编辑实例。

6.5 Polygon 精调

模型生成有效 mask 后,可以进入"Polygon 精调":

  • 拖动顶点改变边界;
  • 双击轮廓边插入顶点;
  • 删除选中顶点,但每个 ring 至少保留 3 个点;
  • 删除轮廓时,关联孔洞也会一起处理;
  • 外轮廓和孔洞分别显示,坐标保存为相对原图的归一化值。

Polygon 模式下点和矩形框工具被禁用,避免模型推理覆盖人工边界。退出 Polygon

模式时,界面可能提示是否放弃 Polygon 修改并返回模型 mask,请根据需要确认。

6.6 缩放和平移

  • Ctrl + 鼠标滚轮:以光标为中心缩放;
  • 鼠标中键拖动:平移;
  • "适应窗口":显示完整图片;
  • "100%":按原始像素比例显示。

7. 保存结果和项目恢复

选择标注文件夹后点击"保存标注",输出结构如下:

text 复制代码
<annotation-directory>/
├── project.json
├── categories.json
├── masks/
│   └── <image>.png
├── instances/
│   ├── <image>.png
│   └── <image>.json
└── states/
    └── g<generation>/
        ├── categories.json
        └── <image-key>/instance-<id>.yml.gz

文件含义:

  • project.json:项目清单、图片信息、实例映射和状态路径;
  • categories.json:类别 ID、名称及 RGB 颜色;
  • masks/*.png:与原图同尺寸的单通道 16 位语义 mask,像素值为类别 ID;
  • instances/*.png:单通道 16 位实例 mask,像素值为图片内实例 ID;
  • instances/*.json:实例 ID 与类别及状态文件的映射;
  • states/:Prompt、decoder feedback、模型 mask、Polygon 和编辑生命周期状态。

只有人工确认的实例进入正式语义/实例 mask;未确认草稿仍会保存在项目状态中,便于

下次继续编辑。每次保存创建新的 generation,并在状态写入完成后更新项目清单。

8. 测试和验证

8.1 运行 CTest

bash 复制代码
ctest --test-dir build-qt --output-on-failure

当前应运行:

  • MobileSamBackend:使用仓库内真实 encoder/decoder 模型;
  • AnnotationSession:验证文件夹、类别、实例和项目持久化。

查看测试列表:

bash 复制代码
ctest --test-dir build-qt -N

8.2 Qt 启动冒烟测试

在无桌面的 CI 或远程终端中可使用 Qt offscreen 平台,程序会在指定毫秒数后退出:

bash 复制代码
QT_QPA_PLATFORM=offscreen \
  ./build-qt/SAMLabeler-MNN --smoke-test-ms 1500

该测试会加载默认模型,因此必须从项目根目录运行并确保模型存在。offscreen 插件

可能输出不支持某些窗口提示能力的警告;只要程序成功启动并按时返回,通常不表示

应用逻辑失败。

8.3 检查文本和改动

开发修改后可执行:

bash 复制代码
git diff --check
git status --short

提交前应特别确认没有误加入构建目录、模型、用户图片、mask 或标注状态。

9. 编译和运行问题解决

排查问题时建议先保留完整的 CMake/编译输出,并记录所用的 MNN、Qt、OpenCV、

编译器和构建目录。不要只截取最后一行错误。

9.1 MNN headers were not found

典型错误:

text 复制代码
MNN headers were not found under .../include

原因:MNN_ROOT/include/MNN/Interpreter.hpp 不存在,或 MNN_ROOT 指向了错误层级。

检查:

bash 复制代码
ls -l /path/to/MNN/include/MNN/Interpreter.hpp

解决:

bash 复制代码
cmake -S . -B build-qt -G Ninja \
  -DMNN_ROOT=/correct/path/to/MNN \
  -DMNN_LIBRARY=/correct/path/to/MNN/build/libMNN.so

MNN_ROOT 应指向包含 include/MNN/Interpreter.hpp 的 MNN 根目录,而不是

include/ 本身。

9.2 MNN runtime library was not found

典型错误:

text 复制代码
MNN runtime library was not found at .../libMNN.so

原因:MNN 尚未生成共享库、库位于其他目录,或缓存中仍保存旧路径。

检查:

bash 复制代码
find /path/to/MNN -name 'libMNN.so' -type f

把找到的真实文件传给 MNN_LIBRARY

bash 复制代码
cmake -S . -B build-qt \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/actual/path/libMNN.so

9.3 CMake 仍使用旧的 MNN 路径

原因:MNN_ROOTMNN_LIBRARY 是 CMake Cache 变量,已有构建目录会记住首次

配置值。

先查看缓存:

bash 复制代码
grep -E '^(MNN_ROOT|MNN_LIBRARY):' build-qt/CMakeCache.txt

直接用新值重新配置通常即可:

bash 复制代码
cmake -S . -B build-qt \
  -DMNN_ROOT=/new/path/to/MNN \
  -DMNN_LIBRARY=/new/path/to/MNN/build/libMNN.so

如果构建目录混入了不同生成器或完全不同环境,建议保留旧目录用于检查,改用新的

构建目录,例如 build-qt-new,而不是直接删除尚未确认用途的目录。

9.4 Could not find Qt5 或缺少 Qt Widgets

典型信息:

text 复制代码
Could not find a package configuration file provided by "Qt5"

检查 Qt 配置文件:

bash 复制代码
find /usr /opt -name Qt5Config.cmake 2>/dev/null | head

如果 Qt 安装在自定义位置,设置:

bash 复制代码
cmake -S . -B build-qt -G Ninja \
  -DCMAKE_PREFIX_PATH=/path/to/Qt/5.15/gcc_64 \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so

也可设置 Qt5_DIR 指向包含 Qt5Config.cmake 的目录。必须安装 Qt 的开发包,而

不只是运行库。

9.5 Could not find OpenCV 或版本低于 4

检查:

bash 复制代码
pkg-config --modversion opencv4
find /usr /opt -name OpenCVConfig.cmake 2>/dev/null | head

自定义 OpenCV 安装可指定:

bash 复制代码
cmake -S . -B build-qt \
  -DOpenCV_DIR=/path/to/opencv/lib/cmake/opencv4 \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so

项目要求 OpenCV 4 的 core、imgproc、imgcodecs 和 highgui 组件,缺少开发头文件或

组件库都会导致配置或链接失败。

9.6 ninja: command not found

原因:使用了 -G Ninja,但系统未安装 Ninja 或不在 PATH

检查:

bash 复制代码
command -v ninja

可以安装 Ninja,或改用系统可用的生成器:

bash 复制代码
cmake -S . -B build-make \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so
cmake --build build-make

不要在同一个构建目录中切换生成器;请使用新的构建目录。

9.7 编译器不支持 C++11

典型表现为无法识别 C++11 语法,或 CMake 报告 C++ 标准能力不足。

检查:

bash 复制代码
c++ --version
cmake --build build-qt --verbose

安装或选择支持 C++11 的 GCC/Clang,并在首次配置新构建目录时指定:

bash 复制代码
CC=/path/to/gcc CXX=/path/to/g++ \
cmake -S . -B build-qt-gcc -G Ninja \
  -DMNN_ROOT=/path/to/MNN \
  -DMNN_LIBRARY=/path/to/MNN/build/libMNN.so

编译器应与外部 MNN 库的 ABI 兼容。

9.8 链接阶段出现 MNN 未定义符号

可能原因:

  • MNN 头文件和 libMNN.so 来自不同版本;
  • MNN 的编译器 ABI、架构或构建选项不兼容;
  • MNN_LIBRARY 指向了错误的同名库。

检查:

bash 复制代码
file /path/to/MNN/build/libMNN.so
file build-qt/SAMLabeler-MNN
ldd /path/to/MNN/build/libMNN.so

确保头文件与库来自同一 MNN 源码树和同一次兼容构建。修改后在新的项目构建目录中

重新配置,避免旧对象文件干扰。

9.9 运行时报 libMNN.so: cannot open shared object file

检查动态链接:

bash 复制代码
ldd build-qt/SAMLabeler-MNN | grep -E 'MNN|not found'
readelf -d build-qt/SAMLabeler-MNN | grep -E 'RPATH|RUNPATH'

优先重新配置到正确的 MNN_LIBRARY 并重新链接。临时运行可使用:

bash 复制代码
LD_LIBRARY_PATH=/path/to/MNN/build:${LD_LIBRARY_PATH} \
  ./build-qt/SAMLabeler-MNN

不要把来源不明或版本不匹配的 libMNN.so 复制到系统库目录。

9.10 程序提示"模型不存在"

无参数启动时,模型路径相对于当前工作目录,而不是相对于可执行文件。

检查:

bash 复制代码
pwd
ls -lh data/models/mobile_sam_encoder.mnn \
       data/models/mobile_sam_decoder.mnn

从项目根目录启动,或显式传入两个绝对路径:

bash 复制代码
./build-qt/SAMLabeler-MNN /abs/path/encoder.mnn /abs/path/decoder.mnn

9.11 模型存在但加载失败

可能原因:

  • 模型不是项目要求的 MobileSAM vit_t MNN encoder/decoder;
  • MNN 运行时与模型版本不兼容;
  • 模型损坏或 encoder/decoder 顺序传反;
  • decoder 不符合静态 8 Prompt 槽位契约。

检查文件大小和校验值,并确认来源:

bash 复制代码
ls -lh /path/to/encoder.mnn /path/to/decoder.mnn
sha256sum /path/to/encoder.mnn /path/to/decoder.mnn

再运行后端测试获得更明确的契约错误:

bash 复制代码
ctest --test-dir build-qt -R MobileSamBackend --output-on-failure

9.12 Qt 报 could not connect to display

原因:当前终端没有可用的 X11/Wayland 显示环境,常见于 SSH、容器和 CI。

只做启动测试:

bash 复制代码
QT_QPA_PLATFORM=offscreen \
  ./build-qt/SAMLabeler-MNN --smoke-test-ms 1500

需要人工操作 GUI 时,应在有桌面会话的终端运行,或正确配置 SSH X11 转发。不要把

offscreen 模式用于实际交互标注。

9.13 Qt 平台插件 xcb 无法初始化

典型信息:

text 复制代码
Could not load the Qt platform plugin "xcb"

检查插件搜索过程:

bash 复制代码
QT_DEBUG_PLUGINS=1 ./build-qt/SAMLabeler-MNN

检查 Qt 插件依赖:

bash 复制代码
find /usr -name libqxcb.so 2>/dev/null | head
ldd /path/to/libqxcb.so | grep 'not found'

根据缺失库安装与当前 Qt 版本匹配的系统依赖,避免混用系统 Qt、Conda Qt 和自定义

Qt 的插件目录。必要时检查并清理当前 shell 中错误的 QT_PLUGIN_PATH,但应先记录

其原值。

9.14 编译进程被 Killed 或内存不足

原因通常是并行编译占用过多内存。

限制并行度:

bash 复制代码
cmake --build build-qt --parallel 1

确认是否由 OOM 引起:

bash 复制代码
dmesg | tail -n 50
free -h

也可关闭其他高内存程序,或在资源更充足的机器上构建。

9.15 修改代码后界面或行为没有变化

检查实际运行的是哪个二进制:

bash 复制代码
realpath build-qt/SAMLabeler-MNN
stat build-qt/SAMLabeler-MNN
cmake --build build-qt --verbose

确认当前源码目录和构建目录匹配:

bash 复制代码
grep '^SAMLabeler-MNN_SOURCE_DIR:' build-qt/CMakeCache.txt

项目移动后,旧构建目录可能仍引用旧绝对路径。此时应在新项目路径创建新的构建目录

并重新配置。

9.16 CTest 找不到测试或测试使用错误模型

先确认配置和测试列表:

bash 复制代码
ctest --test-dir build-qt -N
grep '^SAMLabeler-MNN_SOURCE_DIR:' build-qt/CMakeCache.txt

测试中的模型路径在 CMake 配置时由源码目录生成。项目移动后应重新运行 CMake,

最好使用新构建目录,确保测试引用当前仓库的 data/models/

9.17 图片目录为空或图片没有出现

确认目录包含受支持扩展名:PNG、JPG/JPEG、BMP、TIF/TIFF,并检查当前用户有读取

权限:

bash 复制代码
find /path/to/images -maxdepth 1 -type f | head
namei -l /path/to/images

图像文件夹只负责源图片;如果误选标注输出目录,列表可能没有可识别的源图。

9.18 保存失败或项目无法恢复

检查:

  • 标注文件夹是否已选择;
  • 当前用户是否有目录写权限;
  • 磁盘空间和 inode 是否充足;
  • project.jsoncategories.jsonstates/ 是否来自同一个项目保存过程;
  • 源图片文件名和尺寸是否被外部修改。

诊断命令:

bash 复制代码
df -h /path/to/annotation-directory
df -i /path/to/annotation-directory
namei -l /path/to/annotation-directory

不要手工只移动 project.json 而遗漏其引用的 states/ 文件。迁移项目时应整体复制

标注文件夹,并保留相对目录结构。

10. 问题报告建议

提交问题时建议附上:

  1. 操作系统和 CPU 架构;
  2. cmake --versionc++ --version
  3. Qt、OpenCV 和 MNN 版本;
  4. 完整 CMake 配置命令;
  5. 从第一条错误开始的完整构建或运行日志;
  6. grep -E '^(MNN_ROOT|MNN_LIBRARY|CMAKE_BUILD_TYPE):' build-qt/CMakeCache.txt
  7. ldd build-qt/SAMLabeler-MNN 中与 not found 有关的行;
  8. 是否使用默认模型、显式模型路径、桌面环境或 offscreen 模式。

请勿上传包含隐私的原始图片、业务标注、模型权重或本机凭据。必要时使用可公开的

最小复现数据,并对绝对路径和用户名做脱敏处理。

相关推荐
LoveAmySun1 小时前
AI智能体如何落地公交营运真实业务
大数据·人工智能
深圳雨林凯AI1 小时前
雨林凯AI四方连图技术原理拆解:无缝拼接、元素重排与密度变化的实现
人工智能
DS随心转插件1 小时前
ChatGPT生成的pdf怎么导出 只要加个“AI导出鸭”
人工智能·chatgpt·pdf·deepseek·ai导出鸭
鸽芷咕1 小时前
5 分钟给 Claude/Cursor 接上“实时联网”能力|Bright Data MCP 实测
人工智能
adinnet20261 小时前
辅助写作与文档整理,从会议纪要到标书,让智能体当好“笔杆子“
大数据·人工智能
LadiesAndGentlemen1 小时前
概览篇:世界模型、空间智能与地理空间智能是什么关系
数据库·人工智能·自然语言处理·开源·aigc
网络工程小王1 小时前
【LLM开发实验】强化学习实现原理及实战
深度学习·强化学习·rlhf·ppo·dpo·grpo
fly76327851 小时前
免费篮球高光剪辑开源工具
人工智能