(此版本为低速开源版)变频可见光通信模拟系统使用说明

20 4 月, 2026

本项目在 Windows 上使用 Python 实现一个可见光数据通信模拟系统,包含发射端、接收端、本机 TCP 校准流程、默认测试素材、本地网页界面和桌面 GUI。发射端可以配置为薄膜 PPLN 波导激光变频器或者普通调色 RGB LED,接收端使用常规工业相机参数进行模拟,并支持自动寻找发射光斑、背景去除、字符串还原以及文件恢复。

版本说明

  • v1:保留原有完整可靠通信链路,对应入口为 app.pydesktop_app.pyone_click_test.ps1one_click_test.bat,核心实现位于 vlc_sim/
  • v2:新增的快速文本通信链路,对应入口为 app_v2.pydesktop_app_v2.pyone_click_test_v2.ps1one_click_test_v2.bat,核心实现位于 vlc_fast/
  • v1v2 并行存在,互不替换。需要稳定文件传输、压缩、CRC、Reed-Solomon 与 bundle 时使用 v1;需要更快的文本聊天演示时使用 v2

v2 快速模式概览

v2 面向“尽量快、尽量实时”的文本通信场景,和 v1 的设计目标不同:

  • 去掉 CRC、Reed-Solomon 和时间码联合调制,只使用 RGB 颜色和亮度承载符号。
  • 使用 4 种颜色和 4 档亮度,共 16 个状态,即每符号 4 bit
  • 在通信前根据背景亮度、运动强度和接收帧率自适应选择重复帧数与有效符号率。
  • 根据接收帧率自动切换不同档位策略,当前已包含 standard_30fpsbalanced_45fpshigh_fps_60fpsultra_90fps 四类适配档位。
  • 接收端支持自动光斑搜索、自适应背景抑制、自动速率匹配和可选 GPU / ONNX 路径。
  • 对真实视频路径,接收端会自动评估多个候选光斑中心并选择得分最高的路径;对模拟器视频则会切到 sidecar 引导的低扰动解码模式。
  • 对模拟器自己生成的 mp4,若存在同名 mp4.json sidecar,会自动使用其中的发射位置和重复帧先验,避免稳像和跟踪引入额外漂移。
  • v2 CLI、Gradio 和桌面 GUI 现在都提供独立的状态面板,直接显示当前链路档位、接收模式、检测中心、重复帧和置信度。

v2 模式切换

v2 现在提供显式 link_mode,可在 CLI、Gradio 和桌面 GUI 中切换:

  • short_chat:默认模式,适合短文本和更快的演示路径,header_repeatspayload_symbol_repeats 最低。
  • long_text:为较长文本增加冗余,自动提高头部重复和 payload 重复次数,并偏向更稳的 repeat_frames
  • real_camera:面向真实摄像头或 sidecar 被移除的视频回归,采用更保守的频率/重复帧策略,并默认启用多候选中心搜索。

这三种模式会直接影响:

  • 校准阶段选择的 minimum_repeat_frames
  • 头部重复次数 header_repeats
  • 载荷重复次数 payload_symbol_repeats
  • 状态面板中的 effective_payload_bps

当前默认 v2 演示背景为 test3.mp4,默认投射位置为 x=1000, y=300

功能概览

  • 发射端输入字符串后,先经过压缩和前向纠错,再映射到颜色、亮度和时间频率联合调制的可见光序列。
  • 发射端支持文本消息和任意文件输入,文件在发送前会按固定大小分片,并在接收端自动重组恢复。
  • 对于较长文件,发射端支持按时长上限自动拆分为多段视频 bundle,并在接收端按清单顺序自动恢复。
  • 发射端将可见光序列以逼真的方式渲染到任意固定机位背景视频上,默认背景是当前目录的 test1.mp4
  • 接收端对视频逐帧分析,自动寻找发射位置,并提供稳像、光流跟踪、经典分割和可选 ONNX AI 分割增强模式;默认走轻量路径,最终还原出原始字符串或文件。
  • 发射端和接收端在发送前通过 127.0.0.1 上的 TCP 校准流程协商链路参数,选择吞吐量和稳健性之间最优的配置。
  • 提供 Gradio 本地网页界面、Tkinter 桌面 GUI 和命令行入口,方便测试与演示。桌面 GUI 现已支持进度条、取消任务和首帧预览。
  • 桌面 GUI 还支持直接打开最新输出文件或所在目录,并显示更清晰的阶段日志,方便本机通信联调。

光源模型与常见频率范围

1. 薄膜 PPLN 波导激光变频器

  • 模拟可见输出范围:约 430 nm 到 680 nm。
  • 工程上常见的外部电驱调制量级可以达到约 1 kHz 到 100 kHz,具体取决于激光器、驱动器和调制链路。
  • 本项目中的视频模拟受限于相机帧率,因此真正进入视频解调的有效调制频率被映射为低频离散时间码,保证普通工业相机可以观测到。

2. 普通调色 RGB LED

  • 模拟可见输出范围:约 450 nm 到 650 nm。
  • 常见单片机 PWM 调光频率通常在约 500 Hz 到 20 kHz,取决于 MCU 定时器、驱动管和亮度要求。
  • 本项目同样把高频硬件调制折算成相机可观测的离散时间亮度变化,用于生成和还原视频中的发光轨迹。

算法设计

1. 校准与匹配

发射端和接收端先通过本机 TCP 进行校准。接收端根据相机帧率、噪声和模糊参数,对若干候选链路配置打分,返回最优配置。当前候选集合主要调整如下参数:

  • 每个符号占用多少帧。
  • 可用的时间码集合。
  • 固定的强度等级和 Reed-Solomon 纠错强度。

评分函数优先保证以下条件:

  • 时间码最高频率低于接收端 Nyquist 安全边界。
  • 不超过发射源常见硬件调制能力。
  • 在满足稳健性的前提下优先更高吞吐量。

2. 数据压缩与纠错

文本或文件发送前执行以下处理:

  1. 使用 UTF-8 编码。
  2. 使用 zlib 进行无损压缩。
  3. 追加 CRC32 校验。
  4. 使用 Reed-Solomon 进行前向纠错。

这样可以在解码端对一定数量的符号误差进行恢复,同时用 CRC 防止错误内容被误判为成功解码。文件负载会额外附带文件名、媒体类型、分片大小、分片总数和 SHA256 校验。

3. 联合调制

一个发光符号由三部分共同承载信息:

  • 颜色维度:4 个高区分度颜色索引。
  • 亮度维度:2 个强度等级。
  • 时间维度:4 个时间码,内部由频率和相位组合形成。

因此一个符号携带 5 bit 信息。时间码使用窗口内的离散正弦变化,接收端通过匹配滤波和整符号模板匹配进行识别,从而在时间域和频率域都携带数据。

4. 发射端场景渲染

为了让视频更接近真实场景投射,本项目没有简单地直接叠加纯色圆点,而是做了以下处理:

  • 使用高斯核构建核心光斑和外扩 bloom,但对中心信号强度保留单独下限,避免真实感增强后影响解码稳定性。
  • 使用局部灰度、颜色相似性和模糊趋势估计纹理权重,让光斑贴合墙面、地面、建筑表面等近场承载区域。
  • 对高处天空、远景山体、低纹理蓝色区域和雾化区域施加抑制,避免出现明显不真实的远处整块投光。
  • 支持 classical_surface 投射模式和可选 depth_surface 模式;后者可结合深度 ONNX 模型进一步压制远景区域。
  • 使用局部亮度增益和加性发光混合,保留背景细节和表面起伏,并通过羽化边缘消除突兀方块感。
  • 最后叠加相机模糊、噪声和色彩增益,模拟工业相机成像差异。

5. 接收端自动目标定位与解算

接收端默认不需要手工指定光斑位置,会自动完成以下步骤:

  1. 读取视频前段帧序列。
  2. 下采样后计算时间中值背景。
  3. 统计各像素相对于背景的时变能量。
  4. 对模拟器生成的视频,优先读取同名 mp4.json sidecar 中的发射位置作为先验;对真实录像则取能量峰值作为发射器位置初值。
  5. 在该位置周围建立高斯 ROI 和环形背景区域。
  6. 可选地先执行全局稳像,再在局部窗口内进行经典分割或 ONNX 分割。
  7. 对光斑位置执行光流跟踪,得到逐帧中心点。
  8. 用 ROI 均值减去环形背景均值,得到净发光信号。
  9. 搜索符号起始帧偏移。
  10. 用匹配时间码、颜色向量和强度等级方式解码头部和载荷。

这个方案不依赖大型 GPU 模型,适合普通 PC 在几分钟内处理 10 秒量级的视频。默认实现偏向 CPU 友好。如果后续需要引入更重的 AI 开源模型,比如基于分割网络的目标掩码提取或者视频目标跟踪,也可以在当前结构上继续扩展。

代码结构

  • app.py:命令行和本地网页界面入口。
  • desktop_app.py:Tkinter 桌面 GUI。
  • app_v2.py:v2 命令行和本地网页界面入口。
  • desktop_app_v2.py:v2 Tkinter 桌面 GUI。
  • one_click_test.ps1:一键默认参数通信测试脚本。
  • one_click_test.bat:面向双击或 CMD 环境的一键测试入口。
  • one_click_test_v2.ps1:v2 一键快速文本通信测试脚本。
  • one_click_test_v2.bat:v2 双击版一键测试入口。
  • TECHNICAL_DETAILS.md:扩写后的技术说明文档,包含字符 A 的完整编码与解码示例。
  • vlc_sim/payload.py:文本/文件统一封装、分片元数据和重组恢复。
  • vlc_sim/ai.py:ONNX 模型下载、分割推理与深度估计。
  • vlc_sim/models.py:源、相机和链路配置数据结构。
  • vlc_sim/calibration.py:本机 TCP 校准流程。
  • vlc_sim/codec.py:压缩、纠错、符号映射与时间码。
  • vlc_sim/render.py:场景光斑渲染与相机模拟。
  • vlc_sim/transmitter.py:发射端视频生成。
  • vlc_sim/receiver.py:接收端自动定位与解码。
  • vlc_fast/models.py:v2 设置、链路配置和结果结构。
  • vlc_fast/protocol.py:v2 的 16 状态快速符号协议。
  • vlc_fast/calibration.py:v2 自适应速率拟合与后端选择。
  • vlc_fast/transmitter.py:v2 快速发射视频生成。
  • vlc_fast/receiver.py:v2 自动定位、同步和文本恢复。

安装

当前目录已经按以下依赖实现:

  • numpy
  • opencv-python-headless
  • gradio
  • reedsolo
  • onnxruntime
  • pillow

如果需要重新安装,可以在当前虚拟环境中执行:

g:/toys/.venv/Scripts/python.exe -m pip install numpy opencv-python-headless gradio reedsolo onnxruntime pillow

启动网页界面

g:/toys/.venv/Scripts/python.exe app.py ui --port 7860

启动后打开本机 Gradio 页面,界面包含三个标签页:

  • 校准:模拟发射端和接收端在 127.0.0.1 上通过 TCP 选出链路参数。
  • 发射端:输入字符串或文件,选择背景视频和投射坐标,生成带可见光通信序列的 mp4。
  • 接收端:读取 mp4 或 bundle 清单,自动定位光斑并解码字符串或恢复文件。
  • AI 模型:下载可选的 ONNX 分割模型,或直接下载默认深度模型。

启动 v2 网页界面

g:/toys/.venv/Scripts/python.exe app_v2.py ui --port 7861

v2 网页界面包含 4 个标签页:

  • v2 自适应校准:根据背景视频和接收参数估计 repeat、有效符号率和当前计算后端。
  • v2 发射端:直接把文本编码成 RGB + 亮度快速链路并渲染视频。
  • v2 接收端:自动寻找光斑并恢复文本消息。
  • v2 AI 模型:下载可选 ONNX 模型,供背景抑制 / 中心微调用。

启动桌面 GUI

g:/toys/.venv/Scripts/python.exe desktop_app.py

桌面 GUI 使用 Tkinter 构建,适合本机演示,不依赖浏览器。

启动 v2 桌面 GUI

g:/toys/.venv/Scripts/python.exe desktop_app_v2.py

v2 桌面 GUI 提供独立的校准、发射和接收工作页,默认围绕 test3.mp41000,300 的快速文本链路设计。

桌面 GUI 当前支持:

  • 发射、接收、校准三个工作页。
  • 后台线程执行任务,避免窗口卡死。
  • 进度条与状态文本。
  • 取消当前任务。
  • 自动显示输出视频首帧预览。
  • 一键打开最新输出文件或输出目录。
  • 分阶段执行日志,便于确认校准、渲染、解码是否正常推进。
  • 文件传输时可直接生成 bundle 清单并在接收端载入。

命令行示例

发射端

g:/toys/.venv/Scripts/python.exe app.py transmit --message "hello visible light" --background test1.mp4 --output outputs/transmission.mp4 --source-type rgb_led --x 900 --y 120

文件发射端

g:/toys/.venv/Scripts/python.exe app.py transmit --message "payload file" --input-file tips.txt --background test1.mp4 --output outputs/file_transfer.mp4 --source-type rgb_led --x 900 --y 120 --chunk-size 32

多分卷文件发射端

g:/toys/.venv/Scripts/python.exe app.py transmit-bundle --input-file tips.txt --background test1.mp4 --output-manifest outputs/tips_bundle.json --source-type rgb_led --x 900 --y 120 --chunk-size 32 --max-volume-seconds 10

接收端

g:/toys/.venv/Scripts/python.exe app.py receive --video outputs/transmission.mp4 --source-type rgb_led --output-dir recovered

v2 长文本模式

g:/toys/.venv/Scripts/python.exe app_v2.py transmit --link-mode long_text --message "v2 long text demo" --background test1.mp4 --output outputs/test1_v2_long.mp4 --x 900 --y 120 --parse-fps 24 --frequency 24 --min-frequency 4 --max-frequency 120 --spot-radius 110 --blur 0.32 --noise 0.25 --processing-scale 0.65 --prefer-gpu
g:/toys/.venv/Scripts/python.exe app_v2.py receive --link-mode long_text --video outputs/test1_v2_long.mp4 --parse-fps 24 --frequency 24 --min-frequency 4 --max-frequency 120 --spot-radius 110 --blur 0.32 --noise 0.25 --processing-scale 0.65 --output-dir recovered_v2_test1_long --candidate-search-count 6 --prefer-gpu

v2 真实摄像头风格回归

g:/toys/.venv/Scripts/python.exe tools/run_v2_real_camera_regression.py --preset simulated_real_test3 --background test3.mp4 --message "real camera t3" --x 1000 --y 300 --simulate-real-camera

可用预设保存在 tools/v2_real_camera_presets.json,当前包含:

  • webcam_30fps
  • industrial_60fps
  • simulated_real_test3

多分卷接收端

g:/toys/.venv/Scripts/python.exe app.py receive-bundle --manifest outputs/tips_bundle.json --source-type rgb_led --output-dir recovered_bundle

如需启用增强解析路径,可以按需增加:

g:/toys/.venv/Scripts/python.exe app.py receive --video outputs/transmission.mp4 --source-type rgb_led --output-dir recovered --segmentation-mode classical --tracker-mode optical_flow

下载 ONNX 分割模型

g:/toys/.venv/Scripts/python.exe app.py download-ai-model --url "https://example.com/segmenter.onnx" --output models/segmenter.onnx

下载默认深度模型

g:/toys/.venv/Scripts/python.exe app.py download-depth-model --output models/depth_anything_v2_small.onnx

v2 命令行示例

v2 自适应校准

g:/toys/.venv/Scripts/python.exe app_v2.py calibrate --background test3.mp4 --parse-fps 30 --frequency 90 --min-frequency 30 --max-frequency 240 --spot-radius 96 --processing-scale 0.5 --prefer-gpu

v2 发射端

g:/toys/.venv/Scripts/python.exe app_v2.py transmit --message "v2 快速光通信测试" --background test3.mp4 --output outputs/transmission_v2_fast.mp4 --x 1000 --y 300 --parse-fps 30 --frequency 90 --min-frequency 30 --max-frequency 240 --spot-radius 96 --blur 0.35 --noise 0.35 --processing-scale 0.5 --prefer-gpu

v2 接收端

g:/toys/.venv/Scripts/python.exe app_v2.py receive --video outputs/transmission_v2_fast.mp4 --parse-fps 30 --frequency 90 --min-frequency 30 --max-frequency 240 --spot-radius 96 --blur 0.35 --noise 0.35 --processing-scale 0.5 --output-dir recovered_v2 --candidate-search-count 6 --prefer-gpu

下载 v2 可选 AI 模型

g:/toys/.venv/Scripts/python.exe app_v2.py download-ai-model --url "https://example.com/segmenter.onnx" --output models/segmenter.onnx

启用真实投射模式

g:/toys/.venv/Scripts/python.exe app.py transmit --message "hello realism" --background test1.mp4 --output outputs/transmission_realistic.mp4 --source-type rgb_led --projection-mode classical_surface --x 900 --y 120

如需进一步利用深度先验抑制远景区域,可以改用:

g:/toys/.venv/Scripts/python.exe app.py transmit --message "hello realism" --background test1.mp4 --output outputs/transmission_depth.mp4 --source-type rgb_led --projection-mode depth_surface --depth-model models/depth_anything_v2_small.onnx --x 900 --y 120

一键默认通信测试

powershell -ExecutionPolicy Bypass -File .one_click_test.ps1

或者在 cmd.exe / 资源管理器里直接运行:

one_click_test.bat

这个脚本会使用默认背景与默认投射位置 900,120,并采用内置的稳定烟测参数组合,以字符串 你好,栗子树 进行一次完整的发射和接收测试,并自动校验恢复结果是否一致。

一键 v2 快速通信测试

powershell -ExecutionPolicy Bypass -File .one_click_test_v2.ps1

或者在 cmd.exe / 资源管理器里直接运行:

one_click_test_v2.bat

这个脚本会固定使用 test3.mp4、投射位置 1000,300parse-fps=30、目标频率 90 Hz、光斑半径 96 px,并验证字符串 v2 快速光通信测试 是否能被完整恢复。当前默认自适应结果会选择 repeat=2,对应有效符号率 15 Hz,有效载荷速率约 60 bps

默认测试方法

开发完成后的默认测试素材为当前目录下的 test1.mp4。建议用下面的流程做一次完整联调:

  1. 运行发射端,将一段短字符串或文件投射到 test1.mp4 上。
  2. 记录生成的视频路径,比如 outputs/transmission.mp4outputs/file_transfer.mp4
  3. 运行接收端,对该视频进行自动检测、稳像和解码。
  4. 检查终端或者界面中输出的字符串是否与原始输入一致,或者确认恢复目录中的文件校验正确。

如果你希望直接走内置冒烟测试,可以运行 one_click_test.ps1one_click_test.bat。更详细的编码、调制、同步、解调与纠错过程说明见 TECHNICAL_DETAILS.md,其中还包含整体流程图和字符 A 的时序示意图。

性能与限制

  • 当前实现面向固定机位视频,已增加轻量级全局稳像和局部光流跟踪,但不等价于专业级稳像工具链。
  • 默认接收算法是 CPU 友好的时域和色域联合分析;ONNX 分割属于可选增强路径。
  • depth_surface 模式会在发送端额外执行 ONNX 深度估计,真实感更好,但生成速度会明显慢于经典模式。
  • 默认接收会以 0.5 倍比例缩放视频做解析,以降低 1080p 长视频的处理开销;这不会影响模拟视频的 sidecar 引导解码。
  • 如果视频分辨率较高、发射点太小或者背景运动过强,建议增大光斑半径、降低符号率,或者提高相机帧率参数。
  • 更长的消息会生成更长的视频,因为系统会循环背景视频直到完整承载所有符号。
  • 对于文件传输,当前建议把单分片大小控制在 16 到 64 bytes 之间,以换取更稳的恢复率。
  • 多分卷模式适合较长文件,但整体生成时间与视频长度成正比,建议先用较小测试文件验证参数。