基于Simulink的BPSK灰度图像传输仿真与差值图分析
2026/9/13 4:08:03 网站建设 项目流程

简介:基于Simulink的BPSK灰色图像传输完整项目包,面向计算机、电子信息工程与数学等专业学生,适用于课程设计、期末大作业和毕业设计等场景。项目采用MATLAB/Simulink搭建BPSK调制解调链路,完成灰度图像的无线传输与恢复,并通过差值图直观对比收发差异,帮助理解数字通信与图像处理结合的实际流程。资源包共9个文件,核心包括Simulink模型文件(mdl/slxc)、MATLAB辅助脚本(m)、用于仿真的灰度图像(bmp)、运行结果图(jpg)和数据文件(mat),压缩包整体仅116KB,小巧易下载,内含可直接运行的案例。代码采用参数化编程,参数便于修改,注释清晰,便于二次开发与学习。已有56人学习,适合需要快速搭建通信仿真实验、提升MATLAB建模能力的初学者及高年级学生。

1. Simulink 里传灰度图,BPSK 是比 OOK 更值得先落的方案

拿到“基于 Simulink 的 BPSK 灰色图像传输(含差值图)”这个工程包,先别急着双击 .slx 就跑。标题写齐了三层信息:256 级灰度图要转成比特流,比特流要过 BPSK 调制解调和 AWGN 信道,最后用差值图把逐像素误差亮出来。这是一类典型的通信原理课程设计,也是数字基带系统仿真最常用的入门样板。

为什么标题点的是 BPSK?它用相位差 π 的两个载波表示 0/1,理论误比特率是 Q(√(2Eb/N0)),比相干 OOK 大约低 3dB,而且 Simulink 里调制解调模块参数少、链路直观,特别适合把“图像质量随信噪比变差”的过程做成可视化。适合通信课设、数字传输仿真入门,也适合想同时盯误码率和重建图像的工程师。下面按建模、参数、验证三步展开。

2. BPSK 调制解调的 Simulink 建模:相位偏移、比特映射与判决参数

2.1 反相调制的本质:比特 0/1 对应两个星座点

BPSK 名字里带 Phase Shift,核心动作只有一个:把比特 0 映射到载波相位 0,比特 1 映射到载波相位 π,或者反过来。基带等效模型更简单,调制器输出的复信号实部要么是 +1、要么是 -1,虚部恒为 0,星座图上就是实轴上对称的两个点。接收端要做的事也收敛成一句话:采样点落在实轴哪一侧。

这个“反相”的理解直接决定 Simulink 参数怎么填。模型里的 Phase offset 不是让某个星座点旋转 45°,它表示相干解调时本地载波与发送载波之间的固定相差,通信系统里默认取 0。一旦调制器和解调器的 Phase offset 不一致,星座图整体旋转,判决区域跟着错,误码率会直接蹿到接近 0.5,重建图像里就会铺满雪花点。做图像传输仿真时这个问题最容易在复用别人模型时出现。

2.2 调制与解调模块的参数表:能改的其实就六个参数

Simulink 里做 BPSK 不需要自己画乘法器和振荡器,Communications Toolbox 的 Modulation → Digital Baseband Modulation → PM 路径下有现成模块。常见做法是直接用 BPSK Modulator Baseband 和 BPSK Demodulator Baseband 两个基带模块,载波频率的细节被封装在模块内部。

模块参数名推荐值说明
调制器Phase offset (rad)0.0与解调器保持一致,否则星座旋转
调制器Input typeBit直接接收 0/1 双精度序列,便于对接图像比特流
调制器Output typeComplex baseband实部 ±1、虚部 0,便于示波器观察
解调器Phase offset (rad)0.0必须与调制器完全一致
解调器Decision methodHard decision按判决区域输出 0/1,图像场景够用
解调器Output typeBit输出比特流,直接进误差统计模块

Input type 我一般选 Bit 而不是 Integer。选 Integer 时模块会把输入当作符号序号处理,出现 0/1 之外的值会报错;选 Bit 则每个采样直接对应一个比特,图像串行化之后可以原样送入,不用额外加 Bit to Integer 转换。

提示:解调器的 Decision method 还有 Log-likelihood ratio 和 Approximate log-likelihood ratio,那是软判决路数,需要额外喂噪声方差,适合后面级联 LDPC 解码的场景。只做图像传输对比时,Hard decision 足够说明问题,少一个噪声方差参数就少一处出错源。

2.2.1 两个模块之间的最小连线顺序

调制器输入端接从 Workspace 读出的图像比特流,输出端进 AWGN Channel,再进解调器;解调器输出分两路,一路进 Error Rate Calculation 的 Rx 端口,另一路进 Bit to Integer 做图像还原。全链路用样本式基带结构时,连线之间不要再插入会改变采样率的模块,否则误差统计的 Receive delay 要重新校准。采样率由数据源一侧唯一决定,链路里其他模块的 Sample time 全部保持 -1 继承即可。

2.3 先用几十行脚本把判决逻辑钉死,再回 Simulink 连线

搭模型前,我会先在脚本里把 BPSK 的映射-加噪-判决链路跑一遍,确认门限和噪声方差公式没写错,再进 Simulink 连模块:

rng(1); bits = randi([0 1], 100000, 1); % 10万比特,足够统计到 1e-4 量级 sym = 1 - 2*bits; % BPSK映射:比特0 -> +1,比特1 -> -1 EbN0_dB = 6; EbN0_lin = 10^(EbN0_dB/10); N0 = 1 / EbN0_lin; % 每比特能量归一化为1,反解噪声谱密度 noise = sqrt(N0/2) * randn(size(sym)); rx = sym + noise; bits_hat = double(real(rx) < 0); % 判决门限0:实部为负 -> 判为比特1 ber_est = mean(bits ~= bits_hat); ber_theory = qfunc(sqrt(2*EbN0_lin)); fprintf('仿真BER=%.4e, 理论BER=%.4e\n', ber_est, ber_theory);

这段代码三个参数是关键:sym = 1 - 2*bits把比特 0/1 映射成 +1/-1,幅度取 1 是为了让每比特能量 Eb=1,后面反推 N0 不用除系数;N0 = 1/EbN0_lin来自 Eb/N0 的定义,Eb=1 时 N0=10^(-dB/10);sqrt(N0/2)是实基带噪声的标准差,这样采样点信噪比恰好是 2Eb/N0,理论公式直接对得上。6dB 时仿真值应该和 qfunc(sqrt(2*10^0.6)) 差在千分位附近。

2.4 判决门限为什么可以放心取 0

当 0/1 等概率出现、噪声对称时,最大后验判决点落在两个星座点的中点,也就是实轴 0 处。这里不用调偏门限:如果图像数据里某个比特占比明显高,门限才需要往另一侧偏移一点,但灰度图的像素位去相关之后 0/1 基本均匀,0 门限就是理论最优。模型里真正要盯的是采样时刻,Simulink 固定步长下让解调器采样点和调制器符号边界对齐,否则门限正确也会因为跨符号采样而误判。

3. 灰度图像序列化进 BPSK 模型:数组读、位缓冲与帧长的配合

3.1 uint8 灰度图拆位:de2bi 的位序和列展开顺序

图像进 BPSK 之前必须变成一串 0/1。灰度图每个像素是 uint8,取值 0~255,所以要拆成 8 个比特。常见做法是 MATLAB 里先读图,一次性完成灰度化和拆位,把结果存成 .mat 供 Simulink 读取:

img = imread('lena.png'); if size(img, 3) == 3 img = rgb2gray(img); end img = im2uint8(img); % 强制转 uint8,避免 double 图取值变 0~1 bits = de2bi(img(:), 8, 'left-msb'); % 每个像素一行,MSB 在前 tx_bits = bits(:); % 按列展开成连续比特流 save('img_bits.mat', 'tx_bits', 'img');
3.1.1 位序与展开顺序的一致性

两个细节决定接收端能不能还原:一是'left-msb'让每行第 1 列是最高位,二是bits(:)的展开顺序。de2bi的输出是像素数×8 的矩阵,(:)按列取,得到的是“所有像素的第 1 位、所有像素的第 2 位……”这种位平面交错顺序。接收端只要做对应的reshape(bits_rx, [], 8),一行就是一个像素的 8 位,再用bi2de(rx_bits, 8, 'left-msb')还原像素值。两边位序不一致时,图像不会整体变花,而是每个像素的灰度值错乱,这也是和随机误码最直观的区别。

3.2 从 Workspace 把比特数组读进模型:Simulink 数组读的两个坑

拆好的tx_bits是列向量,Simulink 里最常见的做法是用 From Workspace 模块读取。跑模型之前要先把它包装成带时间信息的信号,否则模块会按固定的 Sample time 采样,时间轴对不上仿真时长:

Rb = 10000; % 比特率 10 kbps,可自行调整 t = (0:length(tx_bits)-1)' / Rb; ts = timeseries(double(tx_bits), t); assignin('base', 'ts_bits', ts);

From Workspace 模块的 Signal 填ts_bits,Sample time 填1/Rb,仿真停止时间设length(tx_bits)/Rb。这里有两个高频坑:第一,模块输出的行列方向取决于 timeseries 的 Data 形状,Data 是列向量时输出也是列,要和 BPSK 调制器的输入维度一致;第二,Sample time 必须等于比特周期而不是 1,否则一个采样点跨多个比特,误码率仿真结果就是伪随机值。如果图像很大,比如 1024×1024,建议先缩小或裁剪,百万比特量级模型也能跑,但调试迭代会明显变慢。

3.3 按样本读还是按帧读:Buffer 参数与仿真的关系

比特流可以一个采样一个比特地喂给调制器,也可以先用 Buffer 攒成帧。两种方式对后续误差统计参数有直接影响:

传输方式采样时间误差统计的 Receive delay适用场景
样本式,无 Buffer1/Rb0 或调制解调延迟课程设计、规模小于 50 万比特
帧式,Buffer 后送N/Rb(N 为帧长)需补偿帧对齐延迟长图像、减少仿真步数

帧式的收益是仿真总步数降为原来的 1/N,模型跑起来更省时间,但 Buffer 会引入延迟,Error Rate Calculation 的 Receive delay 要一起调。Buffer 的 Output buffer size 我一般取 256 或 512,正好是比特率的整数倍,方便后续按帧统计;Buffer overlap 保持 0,重叠只在做加窗和频谱分析时才需要。

3.4 接收端还原:Bit to Integer 与 Reshape 重建图像

接收端解调器输出的是 0/1 比特流,重建图像要反向做三步:先用 Bit to Integer Converter 把每 8 个比特还原成一个 0~255 的整数,参数 Bits per integer 填 8;再用 Reshape 模块把一维向量变回 行×列 的图像矩阵,输出维度直接填原图的size(img);最后在 MATLAB 里用uint8(out_img)转回图像类型。重建图和原图逐像素相减,就是标题里差值图的原料。如果不喜欢在模型里布 Reshape,也可以在 To Workspace 之后用同样的reshapebi2de在脚本里完成还原,模型图更干净,排查连线问题也更方便。

4. AWGN 信道与误码统计:Eb/N0、接收延迟和差值图的对应

4.1 AWGN Channel 用 Eb/N0 模式时的三个必填参数

Simulink 里加噪声用 AWGN Channel 模块,Mode 选 Signal to noise ratio (Eb/N0),这个模式比直接填 SNR 更接近教科书,参数也好对照理论曲线。三个参数最容易填错:

参数名推荐值填错后果
Eb/N0 (dB)0~10 之间扫参太高图像无差异,太低全花
Number of bits per symbol1BPSK 一符号一比特,填 2 会叠错噪声能量
Symbol period1/Rb 秒填错导致实际噪声强度偏移 10log10 量级

按 ±1 幅度、Eb=1 建模时,调制器输出符号平均功率是 1W,AWGN Channel 的 Input signal power 填 1,或者选 Estimate from transmitted signal。注意 Symbol period 不是 Sample time 的别名,它告诉模块每个符号持续多久,用于把 Eb/N0 换算成实际噪声方差;帧式传输下 Symbol period 仍然写 1/Rb,不要写成 N/Rb。

4.1.1 Symbol period 到底起什么作用

模块按 Eb/N0 和符号周期换算出每符号噪声能量,再叠加到信号上。填成 1/Rb 时每个采样点对应一个比特;填成 1 秒,噪声会被放大 10log10(Rb) dB,误码率曲线整体向右偏移一大截。这个现象常出现在从别的模型复制 AWGN 模块、忘记同步参数的场景,扫参曲线对不上理论值的时候,优先检查这里。

4.2 Error Rate Calculation 的 Receive delay 校准

误码率统计用 Communications Toolbox 里的 Error Rate Calculation 模块,它的 Tx 和 Rx 两个输入必须比特对齐。模块参数里的 Receive delay 表示接收比特相对发送比特落后多少个采样周期。样本式且无缓冲时设 0;帧式或者中间插了流水线模块,就得先校准。

校准方法:发送端接一个已知的 PN 序列,用 PN Sequence Generator 生成,接收端对齐后把 Receive delay 从 0 开始往上加,观察模块输出的误码率从 0.5 附近掉到接近理论值的位置,这个值就是真实延迟。误差统计模块的 Output data 选 Workspace,仿真结束自动把结果写到工作区,后面脚本扫参要用它。

4.3 用脚本批量扫 Eb/N0,与理论 BER 对齐

模型验证的核心动作,是让仿真 BER 和 BPSK 理论曲线叠在一张图上。逐次打开 Simulink 仿真再手动改 Eb/N0 太低效,通常用 SimulationInput 批量改参数:

EbN0_list = 0:2:10; num = numel(EbN0_list); simIn(num) = Simulink.SimulationInput('bpsk_img_tx'); for k = 1:num simIn(k) = simIn(k).setVariable('ebno_now', EbN0_list(k)); end out = sim(simIn, 'ShowProgress', 'off'); % 可用 parsim 并行 ber_sim = arrayfun(@(o) o.out_ber(end, 1), out); ber_theory = qfunc(sqrt(2 * 10.^(EbN0_list/10))); semilogy(EbN0_list, ber_sim, 'o', EbN0_list, ber_theory, '-'); legend('仿真', '理论');

setVariable('ebno_now', ...)的前提是模型里 AWGN Channel 的 Eb/N0 参数直接填了变量名ebno_now,而不是数字;To Workspace 输出的out_ber每行是 [误码率, 错误比特数, 总比特数],end,1取最后一行第一列作为整段仿真的最终 BER。低误码率段曲线会抖动,扫到 10dB 以上时每个点至少要给百万比特量级,否则曲线底部会画出一串 0,和理论值对不上。

4.4 一个比特错误和图像上一个像素错误不是一回事

差值图里一个亮点代表一个像素出错,而像素出错的充要条件是它的 8 个比特里至少错一个。假设 BER 为 p、各比特独立,像素错误率是 1-(1-p)^8。这张对照表可以直接用来预判图像在哪个 Eb/N0 开始发花:

Eb/N0 (dB)理论 BER像素错误率图像观感
07.9e-2约 48%几乎无法辨认
41.25e-2约 9.6%大量椒盐噪点
62.4e-3约 1.9%零星噪点,轮廓清晰
81.9e-4约 0.15%肉眼看不出差异
103.9e-6约 0.003%差值图应基本全黑

对照表也解释了差值图为什么重要:BER 到 1e-4 量级时,重建图像肉眼已经看不出差别,只有差值图把残差放大,才能确认误码到底出现在哪些像素位置。

5. 差值图生成、PSNR 核对与批量仿真技巧

5.1 差值图脚本:固定显示范围,别被自动拉伸骗了

接收端 To Workspace 拿到还原后的像素矩阵后,差值图核心计算只有一行abs(double(img)-double(img_rx)),但显示是个坑。直接用imshow(diff_map)会让 MATLAB 自动拉伸灰度范围,一个 255 的误差点会把全图对比度压没,看起来像全黑。正确做法是把显示范围固定:

diff_map = abs(double(img) - double(img_rx)); err_pixels = nnz(diff_map > 0); mse = mean(diff_map(:).^2); psnr = 10 * log10(255^2 / mse); % 峰值信噪比,图像质量标尺 figure; subplot(1,3,1); imshow(img, []); title('发送端原图'); subplot(1,3,2); imshow(uint8(img_rx), []); title('接收端重建'); subplot(1,3,3); imshow(diff_map, [0 64]); colormap(parula); colorbar; title('差值图(0~64截断)');

imshow(diff_map, [0 64])把范围截到 64,0 误差的像素是纯黑,1~64 的误差按亮度梯度显示,小差异也能看见;如果整图误差普遍超过 64,说明当前 Eb/N0 太低,图像本身已经没有分析价值。PSNR 和 err_pixels 两个量一起记,和质量观感互相印证。

5.2 用三件事验证模型没搭错

第一,星座图确认。把解调器输入端信号接到 Constellation Diagram 模块,Eb/N0 在 6dB 以上时应该看到两团清晰落在 (±1,0) 附近的点簇,点簇形状怪异或旋转偏移,说明 Phase offset 或采样时刻有问题。

第二,BER 曲线对齐。把 4.3 节的仿真曲线和理论公式画在一起,偏差超过半个数量级基本可以断定是延迟或噪声参数错误,而不是模型随机性。

第三,误码位置等于差值图位置。用xor(tx_bits(1:numel(rx_bits)), rx_bits)找出错误比特索引,按像素维度折算后和diff_map > 0的像素集合对比,重合度应该接近 100%。不重合基本就是串行化或还原的 reshape 顺序写反了。

5.3 批量仿真的两个提速点

把整张图反复跑多个 Eb/N0 点很耗时,提速不靠改求解器,靠两个习惯:一是用 SimulationInput 配 parsim 并行,多个信噪比点同时跑,总耗时基本等于最慢那一个;二是把 To Workspace 和信号记录关掉,只保留最终统计量,内存占用差一到两个数量级。模型逻辑验证完之后想往硬件走,常见路径是用 Simulink Coder 生成 C 代码,再在 Zynq 上把 AD9361 的 IQ 数据接进这套解调链路,基带算法本身不需要重写,整套脚本里要最后确认的只有 AD9361 的采样率和Rb是否对齐。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询