请输入
菜单

fixSharedMemoryDll — filter.* 命令族接口手册

作者: JT下载

fixSharedMemoryDll — filter.* 命令族接口手册

本文档专门讲 filter.* 命令家族(像素级 2D 图像处理)。

协议总览、命令家族分布、错误码表、共享内存配置等通用内容请看 fixSharedMemory_dll_README.md

适用版本:fixSharedMemoryDll v2.0.0+,FIX 主程序 build ≥ 3685。


1. 命令一览

命令 用途 后端 GPU 必需 输出尺寸
filter.sr FIX 超分辨率(×1 增强 / ×2 / ×4 上采样) libtorch(双模型混合,由 blendRatio 控制 Soft↔Hard) scale1 同尺寸;scale2 ×2(快速档);scale4 ×4

所有 filter.* 命令的输入图像通过共享内存传给服务端,输出图像通过共享内存返回客户端。
并发模型:服务端 fiImageProcWorker FIFO 串行处理所有图像处理请求,无背压。


2. 通用调用结构

2.1 数据结构

c 复制代码
typedef struct FSImageProcParamsC {
    const char* command;          // 必填:"filter.sr"
    const char* paramsJson;       // 可空:命令参数 JSON(UTF-8)
    const char* teachingFile;     // 可空:teach.* 用
    const char* resultPath;       // 可空:服务端落盘路径(filter.* 也支持,命中后跳过 SHM 回传)
                                  //       paramsJson["option.resultPath"] 优先级更高
    int         timeoutMs;        // 0=默认 300000ms
} FSImageProcParamsC;

typedef struct FSImageProcResultC {
    int32_t  procStatus;          // 0=OK;详见错误码表
    int32_t  taskStatus;
    uint32_t outRows, outCols, outChannels;  // 服务端落盘模式下全为 0(SHM 跳过)
    int      outImageType;        // FS_IMAGE_C_RGB24 / FS_IMAGE_C_GRAY8 ...
    uint64_t outStride;
    void*    outImage;            // DLL 分配,必须 fsChannelFreeImageProcResult 释放
                                  // 服务端落盘 / option.returnImage=false 时为 NULL
    char*    resultJson;          // 落盘模式下含 savedPath/savedRows/savedCols/savedChans
    char*    errorMsg;            // 失败时填充
    uint64_t queuedUs;            // 入队等待时间
    uint64_t computeUs;           // 服务端实际计算时间
    uint64_t totalUs;             // 服务端总时间
    int64_t  elapsedMs;
} FSImageProcResultC;

2.2 同步调用模板

cpp 复制代码
#include "fixSharedMemory_api.h"

// 1. 建通道(FIX 必须已运行)
FSChannelHandle ch = fsChannelCreate(nullptr);   // 默认共享内存名 "FIXSharedMemory"
if (!ch) { /* 处理失败 */ }

// 2. 启用接收缓冲(容纳输出图像 + JSON + 余量)
fsChannelEnableImageProcReceiver(ch, 512ULL * 1024 * 1024);

// 3. 配参数
FSImageProcParamsC params{};
params.command    = "filter.sr";
params.paramsJson = R"({"filter.sr.scaleMode":"scale1"})";
params.timeoutMs  = 600000;

// 4. 调用(阻塞)
FSImageProcResultC result{};
int rc = fsChannelSendImageProcAndWait(ch, &params,
    inputBgrBytes, rows, cols, 3,
    FS_IMAGE_C_RGB24,
    static_cast<uint64_t>(cols) * 3,
    &result);

// 5. 用 result.outImage(DLL 分配)

// 6. 释放 + 关闭
fsChannelFreeImageProcResult(&result);
fsChannelDestroy(ch);

2.3 异步调用 + 进度回调

cpp 复制代码
// 注册回调(注册即生效;不注册=不接收对应消息)
fsChannelSetImageProcProgressCallback(ch,
    [](uint32_t reqId, uint32_t done, uint32_t total,
       const char* msg, void*) {
        std::printf("req#%u %u/%u: %s\n", reqId, done, total, msg);
    }, nullptr);

fsChannelSetImageProcCompleteCallback(ch,
    [](uint32_t reqId, const FSImageProcResultC* r, void*) {
        if (r->procStatus == FS_PROC_C_OK) { /* 用 r->outImage */ }
    }, nullptr);

// 发送(立即返回 requestId,0=失败)
uint32_t reqId = fsChannelSendImageProcAsync(ch, &params,
    inputBgrBytes, rows, cols, 3, FS_IMAGE_C_RGB24,
    static_cast<uint64_t>(cols) * 3);

3. 通用 option.* 字段(跨命令共享)

paramsJson 里以 option. 为前缀的字段适用于所有命令,由框架(fiImageProcWorker)解析,不归命令 handler 管。

字段 类型 默认 含义
option.returnImage bool true false = 服务端完全跳过 SHM 图像回传,仅返回 procStatus + resultJson。适合"只要检测结果不要输出图"的场景
option.resultPath string "" 服务端落盘路径。非空时 FIX 用 cv::imwrite 直接写盘,跳过 SHM 回传。优先级高于 FSImageProcParamsC.resultPath 结构体字段

3.1 落盘路径优先级

paramsJson["option.resultPath"] FSImageProcParamsC.resultPath 服务端实际落盘路径
非空 任意 JSON 中的路径
空 / 未设 非空 结构体里的路径
空 / 未设 不落盘(走 SHM 回传)

为什么要双源:结构体字段方便 C 客户端直接用;JSON 字段允许新参数(如 option.resultFormatoption.resultQuality)在不破坏协议的前提下扩展,未来加新落盘选项不必改 FSImageProcParamsC

3.2 落盘成功后的响应

  • r->outImage = NULLr->outRows = outCols = outChannels = 0r->outStride = 0
  • r->procStatus = FS_PROC_C_OK
  • r->resultJson 含:
    json 复制代码
    {
      "savedPath":  "z:/output/foo.jpg",
      "savedRows":  10997,
      "savedCols":  15360,
      "savedChans": 3
    }

客户端不能用 r->outImage != NULL 判断成功——服务端落盘成功后这字段是 NULL。要看 procStatus == FS_PROC_C_OKresultJson.savedPath

3.3 落盘失败的 fallback

cv::imwrite 失败时(路径无权限、磁盘满、扩展名不识别):

option.returnImage fallback
true(默认) 走 SHM 回传,客户端能拿到完整 outImage;resultJson 加 savePathRequested + saveError 标记
false 不 fallback,仅 resultJson 报错

3.4 用法示例

cpp 复制代码
// 方式 A:结构体字段(C 客户端最方便)
FSImageProcParamsC p{};
p.command    = "filter.sr";
p.paramsJson = "{\"filter.sr.scaleMode\":\"scale4\"}";
p.resultPath = "z:/sr_x4.jpg";

// 方式 B:JSON 字段(推荐,便于一次塞所有参数)
p.command    = "filter.sr";
p.paramsJson = "{"
                  "\"filter.sr.scaleMode\":\"scale4\","
                  "\"option.resultPath\":\"z:/sr_x4.jpg\""
               "}";
p.resultPath = nullptr;

// 方式 C:只要 resultJson,不要图、不落盘
p.command    = "filter.sr";
p.paramsJson = "{\"option.returnImage\":false}";

4. filter.sr — FIX 超分辨率

4.1 用途

通过 FIX 训练的 ×4 SR 模型,对 2D 图像做:

  • scale1:与输入同尺寸的画质增强(×4 模型推理后内部 INTER_AREA 缩回原尺寸)
  • scale2:×2 上采样快速档(输入先 cv::resize 0.5× → ×4 模型推理 → 输出 2W×2H)
    • forward FLOPs ≈ 原图的 1/4,~4× 加速
    • 视觉质量:弱于 "scale4 forward 后下采样"(下采样阶段丢了高频信号),但强于纯 cv::resize ×2
    • 适合:显示用、对极细纹理不敏感的场景
  • scale4:×4 上采样(输入 W×H → 输出 4W×4H)

4.2 JSON 参数

字段(必须带 filter.sr. 前缀 类型 默认 含义
filter.sr.scaleMode string "scale4" "scale1"=同尺寸增强;"scale2"=×2(快速档,先 0.5× 下采样再 ×4 forward,速度 ~4× 快但略损细节);"scale4"=×4 上采样
filter.sr.blendRatio float 1.0 Soft↔Hard 混合比例 [0,1];0 = Soft(柔和/去噪),1 = Hard(锐利)
filter.sr.tileSize int 1024 内部 tile 尺寸(≥64)
filter.sr.tileOverlap int 32 tile 重叠像素
filter.sr.batchHint int 1 一次 forward 堆 N 张 tile(OOM 自动减半到 1)

⚠️ 字段名拼写:服务端读 filter.sr.batchHint;写成 batchHint 会拿不到值,掉默认 1。所有 filter.sr.* 字段均带前缀。

4.3 调用要点

  • GPU-only:GPU 不可用/未授权 → procStatus = FS_PROC_C_GPU_UNAVAIL,无 CPU 降级
  • 输入约束channels=3imageType=FS_IMAGE_C_RGB24(实际是 BGR24 字节序)
  • 输入尺寸:任意,无上限。服务端 fiSRTiler 自动切块
  • 输出:scale1 同输入尺寸;scale2 = 2×宽 × 2×高;scale4 = 4×宽 × 4×高
  • 接收缓冲:调用前必须 fsChannelEnableImageProcReceiver(ch, N),N 至少容纳 outRows * outStride + 64KB 余量

4.4 共享内存预算

场景 输入 输出 共享内存最低 EnableImageProcReceiver 最低
scale1 / 15360×10997 BGR 483 MB 483 MB ≥ 1 GB ≥ 600 MB
scale2 / 15360×10997 BGR 483 MB 1.93 GB ≥ 2.5 GB ≥ 2 GB
scale4 / 15360×10997 BGR 483 MB 7.7 GB ≥ 9 GB ⚠️ ≥ 8 GB
scale1 / 4K (3840×2160) BGR 24 MB 24 MB ≥ 256 MB ≥ 64 MB
scale4 / 4K BGR 24 MB 384 MB ≥ 512 MB ≥ 512 MB

scale4 大图需要客户端先在 fiSettings 调大 sd_EC_SharedMemoryX/Y/Z,详见主 README。

4.5 进度信号

filter.srfiSRTiler 处理过程中发 progress:

复制代码
done = 已完成的 tile 数
total = 总 tile 数(≈ ⌈rows/(tileSize-2*overlap)⌉ × ⌈cols/(tileSize-2*overlap)⌉)
message = "SR tile {done}/{total} batch={N}"

15360×10997 / tile=1024 / overlap=32 → core=960 → 16×12 = 192 tiles。

4.6 完整示例

cpp 复制代码
FSImageProcParamsC params{};
params.command = "filter.sr";
params.paramsJson =
    "{\"filter.sr.scaleMode\":\"scale4\","
    " \"filter.sr.blendRatio\":1.0,"
    " \"filter.sr.tileSize\":1024,"
    " \"filter.sr.tileOverlap\":32,"
    " \"filter.sr.batchHint\":1}";
params.timeoutMs = 600000;     // 10 分钟,大图必备

FSImageProcResultC result{};
int rc = fsChannelSendImageProcAndWait(ch, &params,
    bgrBytes, /*rows*/ 10997, /*cols*/ 15360, /*channels*/ 3,
    FS_IMAGE_C_RGB24, /*stride*/ 15360 * 3, &result);

if (rc == FS_API_OK && result.procStatus == FS_PROC_C_OK) {
    printf("SR done: %ux%u in %.2fs (compute=%.2fs)\n",
           result.outCols, result.outRows,
           result.totalUs / 1e6, result.computeUs / 1e6);
    // 处理 result.outImage
} else {
    printf("SR failed: rc=%d procStatus=%d msg=%s\n",
           rc, result.procStatus,
           result.errorMsg ? result.errorMsg : "(null)");
}
fsChannelFreeImageProcResult(&result);

4.7 保存耗时参考(输出落盘)

服务端 option.resultPath 路径或客户端 SHM 回传后落盘,最终都走 cv::imwrite(OpenCV 内部按扫描线流式写入)。编码本身是 CPU bound、单线程,速度强烈受输出格式影响。

以 scale4 / 15360×10997 输出(7.7 GB BGR8)为例:

后缀 实际做什么 估算耗时 输出文件大小 适用
.jpg (quality=95) libjpeg 单线程编码 ~25 s ~300-500 MB 默认;视觉无差
.jpg (quality=75) 同上,更激进压缩 ~17 s ~150-250 MB 偶尔可接受
.bmp 无压缩,直接 dump 字节 ~5-7 s 7.7 GB 最快;磁盘空间换速度
.tif (无压缩) 无压缩 + TIFF 元数据 ~5-7 s 7.7 GB 同 BMP,元数据更丰富
.tif (LZW) LZW 单线程压缩 ~30 s+ ~4-5 GB 慢,不推荐
.png libpng + zlib ~60 s+ ~3-5 GB 真实图像压缩比低且很慢,不推荐

4.7.1 用 scale2 间接缩短保存

scale2 输出是 scale4 的 1/4 大小(1.93 GB vs 7.7 GB),所有保存格式的耗时按比例降低 ~4×。组合最优:scaleMode=scale2 + .bmp ≈ 1-2 秒落盘。

4.7.2 服务端 vs 客户端落盘的耗时差别

两条路径都走 cv::imwrite编码耗时本质相同。差别只在 SHM 大数据传回这段:

路径 传输 SHM 大数据 服务端 cv::imwrite 客户端 cv::imwrite
option.resultPath 命中(服务端落盘) 跳过 ~5-25 s(按格式)
默认(SHM 回传 + 客户端落盘) ~5-8 s(7.7 GB 通过 receiver SHM) ~5-25 s(按格式)

scale4 大图想最快,option.resultPath 让服务端直接写盘——免了 SHM 7.7 GB 的来回。

4.8 与 WL 控件的关系

WL UI 中的"FIX SR"滤镜 走独立路径fiWindowLevelWidget::applyFIXSR),走共享内存通道,fiSRTiler

但两条路径共享同一个 fiModelManager 单例和同一个 GPU。为防止并发撞 CUDA context:

  • fiModelManager::inferenceFIXSR_* / _batch 入口由 m_srInferenceMutex 保护
  • WL UI 与共享内存通道同时触发 SR 时,后到的请求等待先到的完成
  • 这是修 bug,不是回归(之前并发会撞 CUDA context,可能崩溃)

5. 错误码

名称 含义 处理建议
0 FS_PROC_C_OK 成功 result.outImage
-100 FS_PROC_C_BAD_COMMAND 命令名错(拼写错或前缀不对) 检查 params.command
-101 FS_PROC_C_BAD_PARAMS JSON 参数解析失败 检查 JSON 语法、字段名前缀
-102 FS_PROC_C_BAD_INPUT 图像类型/通道不支持 转 BGR24 / GRAY8
-103 FS_PROC_C_GPU_UNAVAIL GPU 不可用/未授权 filter.sr 必须 GPU;其它命令不应触发此错
-104 FS_PROC_C_OOM 显存或主机内存耗尽 减小 tileSize/batchHint
-105 FS_PROC_C_CANCELED 客户端取消 检查取消逻辑
-106 FS_PROC_C_TIMEOUT 超时 提高 timeoutMs
-200 FS_PROC_C_INTERNAL 推理/处理内部错 result.errorMsg

6. 服务端处理链(读者视角)

复制代码
客户端 fsChannelSendImageProcAndWait("filter.<name>", ...)
    │
    │ 共享内存写包 (FS_DATA_IMAGE_PROC_REQ + JSON params + image bytes)
    ▼
fixSharedMemoryManager::processPacket   (fiCore)
    │
    ▼
fiTaskScheduler::onSharedImageProcReceived
    │ 拷贝图像 + JSON → SharedMemoryTask → 入 m_detectQueue
    ▼
fiImageProcWorker (独立 QThread,FIFO 串行消费)
    │ 解析 JSON / 路由 cmd 前缀
    ▼
fiImageProcFilter::runFilter("filter.sr", ...)
    └── filter.sr → fiSRTiler::process → fiModelManager::inferenceFIXSR_*_batch
    │
    ▼
output → 共享内存写回 / 服务端 cv::imwrite 落盘 → 客户端

相关文档

上一个
DDS 预热操作说明
下一个
FIX 训练系统 (FTS)
最近修改: 2026-05-04Powered by