简介:本资源是一份面向计算机及相关专业本科生的Authorware多媒体实验报告,记录“文字的滚动效果”的完整实现过程,重点讲解显示、等待、运动、擦除等图标在动态文字展示中的组合应用。报告按实验步骤展开,包含背景与文字导入、移动路径调整、等待时间控制、多种擦除与显示特效设置等内容,并覆盖马赛克、从左往右、以相机光圈开放等典型特效,适合学习多媒体制作、交互式课件设计或备战Authorware实验考核的读者参考。压缩包共1个doc文档,约16.27MB,便于直接阅读和对照练习。该资源已有460人学习,报告内容翔实,既能帮助理解多媒体软件的基本操作流程,也能为完成类似文字动画作品提供具体示例与思路借鉴。
1. 多媒体技术及应用实验报告:先弄明白这份报告在证明什么
写实验报告,最怕的不是程序跑不动,而是程序跑通了,面对一句“为什么这么设参数”却答不上来。做《多媒体技术及应用》这门课的实验,通常要拿图像、音频、视频各做一组处理:图像走灰度化、直方图、滤波、边缘检测,音频走采样读取、FFT 频谱、滤波,视频走帧提取和运动检测。报告要证明的,不是你“运行过程序”,而是你理解多媒体数据是怎么被采样、存储、变换和过滤的。这篇笔记按这三条线,给出能直接照着改的完整流程,并把最容易让人翻车的环境兼容、参数选择和结果呈现问题单独拎出来讲。适合正在赶实验报告的同学,也适合需要快速搭一套多媒体验证流程的工程师。
2. 图像处理实验:从灰度化、直方图到空间滤波与边缘检测
2.1 实验环境选型:为什么用 Python + OpenCV 而不是 MATLAB
多媒体课程里很多人默认用 MATLAB,因为教材里的示例代码很多是它的。我个人的习惯是 Python + OpenCV,理由很现实:第一,OpenCV 的图像数据结构就是 numpy 数组,灰度图、直方图、滤波、边缘检测都能直接对矩阵做运算,概念和教材里的“二维离散信号”一一对应;第二,Python 环境在不同人的机器上复现成本低,课程报告经常需要互相检查和现场演示,只有特定电脑上才能跑的环境很容易出问题;第三,OpenCV 封装了图像、视频的统一读写接口,后面音频和视频实验能在同一个环境里完成。
python -m venv mm_env source mm_env/bin/activate # Windows PowerShell 用 mm_env\Scripts\Activate.ps1 pip install opencv-python numpy matplotlib scipy第一行创建虚拟环境,避免把包装进系统 Python。第三行里 opencv-python 提供 cv2,numpy 提供数组运算,matplotlib 负责画直方图和频谱图,scipy 在后面音频滤波时会用到。建好环境后,用python -c "import cv2; print(cv2.__version__)"确认版本。OpenCV 不同大版本之间 API 变化很大,网上很多代码是 3.x 写的,直接贴进 4.x 环境会报错,这一点我后面单独展开。
2.2 灰度化与直方图:读懂图像的数据表示
图像实验的第一步几乎都是从灰度化开始的。彩色图在 OpenCV 里读进来是 BGR 三通道数组,灰度化就是把一个 (H, W, 3) 数组压缩成 (H, W) 单通道。OpenCV 的 cvtColor 用的是加权平均法,系数不是 1/3,而是 Y = 0.114B + 0.587G + 0.299R,因为人眼对绿色最敏感,绿色通道权重最高。报告里如果能写出这三个系数并解释为什么不是平均分配,往往比贴一大段代码更能说明你理解了本质。
import cv2 import numpy as np import matplotlib.pyplot as plt # 读入彩色图,BGR 顺序;路径不规范时 imread 返回 None img_bgr = cv2.imread('demo.jpg') if img_bgr is None: print('图像读取失败,请检查路径') exit() # 灰度化:内部完成加权平均 img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY) # 统计 0~255 灰度值的频数,再归一化成概率 hist = cv2.calcHist([img_gray], [0], None, [256], [0, 256]) hist_p = hist.ravel() / hist.sum() plt.figure(figsize=(10, 4)) plt.subplot(1, 2, 1) plt.imshow(img_gray, cmap='gray') plt.title('gray image') plt.axis('off') plt.subplot(1, 2, 2) plt.plot(hist_p, color='black') plt.xlabel('intensity') plt.ylabel('probability') plt.tight_layout() plt.savefig('gray_hist.png', dpi=150)calcHist 第二个参数[0]表示统计第 0 通道,灰度图只有一通道所以写 0。hist.sum()归一化很关键:如果直接画频数,纵轴是像素个数,两张不同尺寸图片的直方图没法对比;归一化成概率后,分布形态才是真正有比较意义的特征。保存成 150 dpi 的 PNG 而不是 JPG,也是避免后续排版时被二次压缩产生伪影。延伸一步,可以把 BGR 三个通道各自的直方图和灰度直方图放在一起,观察三通道重叠区域与灰度分布的对应关系,这个对比图适合放在报告里的“分析与讨论”。
2.3 空间滤波:核大小与 sigma 的选择逻辑
空间滤波的实验点通常放在噪声抑制上,最常见的是给灰度图加椒盐噪声,然后比较三种滤波器。均值滤波是最基础的卷积操作,输出像素是核窗口内所有像素的平均;高斯滤波的核权重按二维高斯分布衰减,sigma 控制权重集中程度;中值滤波不做乘法,它取窗口内像素排序后的中位数,对椒盐噪声有天然优势。
# 三种滤波,核大小统一选 (5,5) img_mean = cv2.blur(img_gray, (5, 5)) img_gauss1 = cv2.GaussianBlur(img_gray, (5, 5), 0.8) img_gauss2 = cv2.GaussianBlur(img_gray, (5, 5), 2.0) img_median = cv2.medianBlur(img_gray, 5)高斯滤波第三个参数 sigmaX 的直观效果是:sigma 越大,核内像素权重越分散,平滑越强,但边缘过渡带也越宽。核大小 (5,5) 和 sigma 之间不是随便组合的,OpenCV 里 sigma=0 时会根据核大小自动计算一个值,但实验要做参数分析,建议显式传一个大于 0 的数。
实操时我的习惯是先固定核大小,扫描 sigma,观察边缘清晰度。肉眼评价总是不够客观,这时可以在报告里放一张“同一区域局部放大”的对比图,再用边缘检测统计整幅图的梯度幅值变化。这里有一个容易忽略的边界问题:核大小越大,图像四边越容易出现“黑边”伪影,因为边界像素没有完整邻域。报告里可以对比borderType不同取值的影响,不过课程实验一般不需要深挖,知道有这个坑就行。
2.4 边缘检测:Sobel、Canny 的参数视角
边缘检测是图像实验里最容易翻车也最容易出效果的一节。Sobel 算子的本质是两个方向的差分滤波器,一个响应水平边缘,一个响应垂直边缘。注意输出要用 CV_64F 而不是 uint8,因为差分结果可能为负,uint8 会截断负值。
sobel_x = cv2.Sobel(img_gray, cv2.CV_64F, 1, 0, ksize=3) sobel_y = cv2.Sobel(img_gray, cv2.CV_64F, 0, 1, ksize=3) sobel_mag = cv2.magnitude(sobel_x, sobel_y) sobel_out = cv2.convertScaleAbs(sobel_mag)cv2.magnitude计算两个方向梯度的模长,比直接把两个方向相加合理。convertScaleAbs把浮点结果线性映射到 [0, 255] 并转成 uint8,方便显示和保存。Sobel 输出的是梯度强度图,它本身不是二值边缘,后面还需要阈值化。
Canny 是比 Sobel 高一层的算法,内部包括高斯平滑、梯度计算、非极大值抑制、双阈值检测和边缘连接。很多人写报告只说“双阈值”,其实真正要理解的是两个阈值的配合逻辑。
edges_loose = cv2.Canny(img_gray, 30, 110) edges_strict = cv2.Canny(img_gray, 80, 200)threshold1 和 threshold2 的含义:梯度幅值大于 threshold2 的点被当成强边缘保留;介于 threshold1 和 threshold2 之间的点,只有与强边缘相连才保留。所以 threshold1 是候选门槛,threshold2 是确定门槛。经验做法是先看 Sobel 幅值直方图,取第 70 分位和第 90 分位作为初始值再微调。固定阈值对光照变化很敏感,同一个场景白天晚上用同一组阈值,结果会完全不同。这种“黑匣子”感最强的地方,恰恰是报告里最值得写参数讨论的部分。
Sobel 与 Canny 的对比可以做成一张小表放进报告:
| 项目 | Sobel | Canny |
|---|---|---|
| 输出内容 | 梯度幅值图 | 二值边缘图 |
| 内部处理 | 差分近似 | 平滑 + 梯度 + NMS + 双阈值 |
| 主要参数 | dx, dy, ksize | threshold1, threshold2 |
| 适用场景 | 需要梯度方向信息的流程 | 需要干净轮廓的检测流程 |
| 计算开销 | 小 | 中 |
3. 音频处理实验:从 WAV 采样到 FFT 频谱与滤波器
音频实验在多媒体课里通常要求完成三件事:读懂 WAV 采样参数、从时域波形看信号、用 FFT 变换到频域,然后实现一个简单滤波器。音频和图像最大的差异是它是一维时间序列,几秒钟 44.1kHz 采样就是几十万个样本,实验重点从空间结构变成了频率结构。
3.1 WAV 文件结构:先从头部读出参数
处理音频之前先读头,这是一个必须养成的习惯。WAV 头里记录了采样率、位深、声道数,这些参数直接决定后面怎么解析数据。用 Python 的 wave 模块就能读,不需要额外解码器。
import wave import numpy as np wav_path = 'record.wav' with wave.open(wav_path, 'rb') as wf: n_channels = wf.getnchannels() samp_width = wf.getsampwidth() samp_rate = wf.getframerate() n_frames = wf.getnframes() raw = wf.readframes(n_frames) print(f'声道数={n_channels}, 位深={samp_width*8}bit, 采样率={samp_rate}Hz, 时长={n_frames/samp_rate:.2f}s') audio = np.frombuffer(raw, dtype=np.int16)16bit 位深对应 int16 有符号整数,音量的正负半周都能表示。如果是 8bit,就要用 uint8 并减去 128 做零偏移校正。如果是 2 声道,raw 里左右声道是交错排列的,需要 reshape 拆开:
if n_channels == 2: audio = audio.reshape(-1, 2) left = audio[:, 0] right = audio[:, 1]报告里要写出两个换算:时长 = n_frames / samp_rate,单声道数据量 = n_frames × samp_width 字节。这两个式子写对了,说明你对 WAV 存储格式真正理解了。实际音频文件末尾可能有填充字节,在高版本 Python 的 wave 模块里通常会自动处理,但如果你用别的方式读文件,记得按n_frames * n_channels截断数组,避免波形末尾出现异常竖线。
3.2 时域到频域:FFT 频谱分析的完整实现
FFT 频谱分析是音频实验的核心。我会先讲清楚一个关键点:连续时间信号的频谱在计算机里只能用有限长样本的 DFT 近似,FFT 是 DFT 的快速算法。做实验时最容易出问题的不是算法本身,而是“取多长一段”和“要不要加窗”。
N = 8192 start = max(0, (len(audio) - N) // 2) segment = audio[start:start + N].astype(np.float64) # 取中间段,避开录音起始噪音 spectrum = np.fft.rfft(segment) freqs = np.fft.rfftfreq(N, d=1.0 / samp_rate) mag = np.abs(spectrum) / N # 除以 N 才是真实幅值近似 mag_db = 20 * np.log10(mag + 1e-10) # 转 dB,避免零幅值取 log 报错 plt.figure(figsize=(12, 4)) plt.plot(freqs, mag_db, linewidth=0.8) plt.xlabel('Frequency (Hz)') plt.ylabel('Magnitude (dB)') plt.xlim(0, samp_rate / 2) # 奈奎斯特频率 plt.savefig('fft_spectrum.png', dpi=150)语音信号里低频能量通常远大于高频,线性幅值画出来高频部分就是一条平线,转成 dB 后高低频差异能同时被看到。rfft比fft更省:实数信号的频谱关于中点共轭对称,后半段没有额外信息,rfft 只保留非负频率,长度正好是 N/2+1。
加窗问题是报告里的加分项。直接截取 8192 个样本相当于乘了矩形窗,频谱有明显旁瓣。给数据乘汉宁窗能压低旁瓣,代价是主瓣变宽:
window = np.hanning(N) segment_win = segment * window spectrum_win = np.fft.rfft(segment_win) mag_win = np.abs(spectrum_win) / N把加窗前后的频谱叠在一张图里,标注出主瓣和旁瓣位置,这个对比图比很多推导更直观。需要注意加窗前如果把时域波形也画出来,数据首尾会被窗压低到接近 0,这是正常现象,不是数据坏了。
3.3 低通与高通滤波:为什么滤波后会有“毛刺”
滤波这一节看似简单,翻车率却不低。最常见的做法是“移动平均低通”,也就是对音频序列做卷积,核里全是相同权重。
def lowpass_moving(x, window=15): kernel = np.ones(window) / window return np.convolve(x, kernel, mode='same') filtered = lowpass_moving(audio.astype(np.float64), window=15) filtered = np.clip(filtered, -32768, 32767).astype(np.int16)mode='same'得到长度不变的滤波结果,但它在边界补零,前后几十个样本会平缓“塌陷”,所以画图时跳过开头一小段更干净。做完卷积后一定要np.clip到 int16 范围再转回整数,否则波峰超过 32767 的样本在类型转换时发生截断,播放出来就是“咔哒”爆音。这是我见过最多的音频实验翻车点。
注意:滤波后写回 wav 前,先打印
filtered.min()和filtered.max(),确认没有超出 int16 范围。这个习惯能省掉很多爆音问题。
高通滤波器最常见的做法是用原始信号减去低通信号,因为低通滤掉的是低频成分,相减后留下的就是高频成分。这种互补滤波在概念上很好理解,报告里可以用一个图验证:低通信号与原始信号相减后,波形里确实看不到缓慢变化的低频部分。
如果课程对滤波器有频率指标要求,比如“截止频率 1000Hz,衰减 40dB”,移动平均就撑不住了。这时候用 Butterworth 双向滤波更可靠:
from scipy.signal import butter, sosfiltfilt sos = butter(4, 1000, 'low', fs=samp_rate, output='sos') filtered_butter = sosfiltfilt(sos, audio.astype(np.float64))sosfiltfilt做双向零相位滤波,避免普通 IIR 滤波带来的相位偏移,语音听起来不会发闷。butter第二个参数 1000 是截止频率,fs=samp_rate显式指定采样率,避免分子分母换算错误。报告里配一张“滤波前后频谱叠加图”和滤波器频率响应曲线,就是一份很扎实的音频实验。
4. 视频处理实验:帧提取、帧差法与背景减除
视频本质上是随时间变化的图像序列,实验通常聚焦两方面:怎么从视频文件里稳定地把帧读出来,以及怎么用相邻帧差异检测运动区域。前者是工程问题,后者是算法原理和参数问题。
4.1 用 VideoCapture 读视频:帧率、尺寸、解码格式先确认
刚开始写视频实验时,很多人直接把视频路径丢给cv2.VideoCapture就开始 read,结果ret一直是 False,代码没问题却就是读不出来。原因多半是解码器缺失。OpenCV 本身不内置全部视频解码器,mp4 里的 H.264 编码需要系统里有对应解码库。
import cv2 cap = cv2.VideoCapture('demo.mp4') if not cap.isOpened(): print('视频打开失败:先换一个 avi 测试排除解码器问题') exit() fps = cap.get(cv2.CAP_PROP_FPS) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) print(f'fps={fps}, 分辨率={width}x{height}, 总帧数={total}')如果fps读到 0,说明创建视频捕获对象有问题,不要继续往下算。实验常见做法是每隔round(fps)帧保存一帧,正好对应每秒 1 帧的采样。注意cap.get返回的是 float,转 int 要显式写。逐帧处理完记得cap.release()释放文件句柄,Windows 上不释放会导致文件被占用,后续其他程序打不开。
4.2 帧差法做运动检测:阈值的敏感度
帧差法是最直观的运动检测:连续两帧做差,像素值变化大的区域就是运动区域。代码很短,但阈值特别敏感。
prev_gray = None motion_ratio_list = [] while True: ret, frame = cap.read() if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (5, 5), 1.0) # 降噪再差分,避免传感器噪点误报 if prev_gray is None: prev_gray = gray continue diff = cv2.absdiff(gray, prev_gray) _, thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY) thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8)) motion_ratio = (thresh > 0).mean() # 运动像素面积占比 motion_ratio_list.append(motion_ratio) prev_gray = gray阈值 25 是经验值。更稳的做法是用直方图分位数:算出 diff 幅值数组的第 90 百分位,用它当阈值,在不同光照的视频里适应性更好。(thresh > 0).mean()算出二值图白色像素占比,按帧序号画成折线,横轴除以 fps 就是时间秒数。报告里放这张“运动面积占比曲线”,比贴十几帧二值图更能说明问题。
帧差法有两个天然弱点:检测出的运动区域只有目标外轮廓边,目标内部因为前后帧差异小会被判定为静止;运动速度很慢时,前后帧像素差太小,阈值稍微抬高就检测不到。所以帧差法适合做“有没有发生运动”的粗检测,不适合做精确目标分割。
4.3 背景减除 MOG2:适用场景与参数退出
背景减除是帧差法的增强版,它对每个像素维护一个或多个高斯模型来描述背景,当前帧像素分布与背景模型差异太大时判定为前景。下面是 MOG2 的典型用法:
mog = cv2.createBackgroundSubtractorMOG2( history=200, varThreshold=32, detectShadows=True ) while True: ret, frame = cap.read() if not ret: break fgmask = mog.apply(frame) # MOG2 的阴影像素输出为 127,用阈值排除 _, fg_bin = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY) fg_bin = cv2.morphologyEx(fg_bin, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))history=200表示用最近 200 帧估计背景,历史太短时背景模型不稳定,背景容易闪烁;varThreshold越大判定越迟钝,对光照变化越不敏感;detectShadows=True会输出阴影标记,但阴影在 mask 里的值是 127 而不是 255,不处理就会把影子当前景,人走过时影子可能成为最大一块前景区域。
帧差法和 MOG2 放在同一段视频里对比,报告可以这样呈现:
| 对比项 | 帧差法 | MOG2 背景减除 |
|---|---|---|
| 背景建模 | 无 | 每像素高斯混合模型 |
| 计算量 | 小 | 较大 |
| 慢速运动 | 容易漏检 | 相对稳定 |
| 阴影处理 | 无法区分 | 有阴影标记通道 |
| 适用场景 | 简单固定场景 | 固定摄像头长时间监控 |
MOG2 不处理摄像头抖动,手持拍摄的视频里前景会大面积闪烁。如果实验素材是手持拍的,报告里讨论这一局限比硬调参数更有价值。
5. 实验报告避坑:环境、参数与结果呈现的排查手册
写这份报告最容易出现的三类问题,我分别见过不止一次:环境层面版本错位导致代码报了奇怪的错;算法层面归一化和阈值问题让图表没法解释;结果呈现层面图多但缺少证据,追问一句就接不上。排查顺序也应该是环境、算法、呈现,不要一上来就怀疑自己算法写错了。
5.1 环境与 API 兼容:版本差异让人翻车
现象:某同学从网上找了一段轮廓检测代码,运行到cv2.findContours报错,提示值解包数量不对。
原因:很多旧代码基于 OpenCV 3.x,findContours 返回 3 个值;现在主流装的是 OpenCV 4.x,只返回 2 个值。代码不是自己写的,报错位置也不在算法逻辑上。
解决:先确认版本,python -c "import cv2; print(cv2.__version__)"。4.x 下改成:
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)现象:同一个图用 cv2.imshow 显示正常,用 matplotlib 的 imshow 显示时颜色发蓝发紫。
原因:OpenCV 读入是 BGR 顺序,matplotlib 期望 RGB 顺序,直接显示把通道次序搞反了。
解决:传给 matplotlib 前先img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)。用 cv2.imwrite 保存不需要转回,直接写 BGR 就对了。
现象:视频文件用播放器能正常打开,cv2.VideoCapture 读出来的 ret 一直是 False。
原因:播放器自带解码器,OpenCV 依赖系统解码库,某些精简环境缺 H.264 解码库。
解决:把素材转成 AVI(编码用 MJPG)再试,或换一个能调起 ffmpeg 后端的 OpenCV 安装方式。报告里把素材编码格式和解码依赖写进环境说明,会显得更严谨。
5.2 算法参数与声音数值:结果不对先查归一化和阈值
现象:图像直方图画出来是一条横线,峰谷完全看不清。
原因:没有归一化,纵轴是像素个数而不是概率。不同图片像素总数不同,直接用频数画直方图,分布形态被纵轴量级压扁。
解决:hist_p = hist.ravel() / hist.sum(),画归一化概率。要对比两张不同尺寸图片,这个步骤必不可少。
现象:FFT 频谱图数值大得离谱,各频率都像在同一条平线上。
原因:频谱幅值没除以样本数 N,也没转 dB。线性幅值跨几个数量级时,小信号全被压平。
解决:mag = np.abs(spectrum) / N后转 dB,x 轴截断到samp_rate / 2,y 轴用20 * np.log10(mag + 1e-10)。
现象:滤波后的音频保存成 wav,播放时出现“咔哒”爆音。
原因:处理过程中 int16 转 float 后卷积结果绝对值超过 32767,直接astype(np.int16)截断产生刺耳噪声。
解决:转回整数前先np.clip(filtered, -32768, 32767)。低频滤波输出也要检查 min/max 再转 int16。
5.3 结果呈现:“看图说话”也要有证据链
现象:报告里贴了十几张图,每张图下面只有一句“实验结果如图所示”。
原因:把实验报告当成了截图集锦。评审关心的是:输入是什么、参数是什么、同类参数下哪个变化显著、你从图里读出了什么规律。没有这些,图只是装饰。
解决:每一节按“输入样本 → 处理参数 → 输出结果 → 可量化指标”组织。图像实验给 PSNR 或梯度幅值均值,音频给频谱峰值频率和能量占比,视频给运动面积占比曲线。图要统一尺寸、统一 colormap,灰度图一律cmap='gray',存 PNG 不存 JPG。
现象:同一实验换一组参数,结果和别人的差别很大。
原因:没有记录完整参数链。图像处理里任何一个预处理步骤,比如是否先转灰度、是否先高斯模糊,都会影响后续输出。
解决:报告里放一张“实验条件表”:输入文件、分辨率、预处理方式、核心参数、运行时间。这张表在答辩时是最直接的辩护材料。
6. 验证进阶:参数扫描与客观指标,让报告经得起追问
参数扫描是报告里性价比最高的一步。比如高斯滤波的 sigma、Canny 的双阈值,手动一组组试既花时间又容易漏掉规律。用一个循环批量跑完,把结果拼成网格对比图,参数变化对效果的影响一目了然:
sigmas = [0.5, 1.0, 2.0, 3.0] fig, axes = plt.subplots(2, 2, figsize=(10, 8)) for i, s in enumerate(sigmas): blurred = cv2.GaussianBlur(img_gray, (5, 5), s) axes[i // 2, i % 2].imshow(blurred, cmap='gray') axes[i // 2, i % 2].set_title(f'sigma={s}') axes[i // 2, i % 2].axis('off') plt.tight_layout() plt.savefig('sigma_scan.png', dpi=150)只看图容易陷入“这张好像还行”的主观判断。给每个结果配一个客观指标,效果会扎实很多。图像处理里最常用的是 PSNR:
def psnr(original, processed): mse = np.mean((original.astype(np.float64) - processed.astype(np.float64)) ** 2) if mse == 0: return 100.0 return 10 * np.log10(255 ** 2 / mse)把每个 sigma 的 PSNR 值写进子图标题,报告里就多了一条量化结论:“sigma 越大,PSNR 越低,细节损失越明显”,而不是一句“看起来更模糊”。音频实验同理,可以扫描不同截止频率,记录滤波前后能量变化;视频实验扫描不同阈值,记录运动面积占比曲线的抖动程度。
我自己写这类报告有过一个教训:把所有参数调成看起来最顺眼的结果,图片很漂亮,但被问“为什么取这个值”时说不出来。后来改成所有实验先跑参数扫描,从趋势里挑“既能说明问题又符合预期”的组合,顺便把趋势图也放进附录。这样写出来的报告,答辩时能明确说出“参数不是随手拍的,是扫描出来的”。多媒体实验报告做到这个程度,看报告的人会相信你真的理解了处理流程。希望这份笔记能帮到你,写实验报告不是把代码跑通就结束,真正的进步在于你能不能用数据证明每一步操作有效。
本文还有配套的精品资源,点击获取