最近在调试一个相机实时叠加功能时,遇到了一个很有意思的问题:明明前景图是一张带透明背景的 PNG,叠加到画面上却总是带一圈黑色边框,怎么调 blend 参数都不对。折腾了大半天才发现,问题不在透明度,而在 alpha 通道的处理方式上。这个 overlay 功能看起来简单,真正落到代码里却有不少细节。
本文就来完整拆解图像叠加(Overlay)的核心原理、OpenCV 实现方式、相机实时叠加应用,以及高频报错和工程优化思路。无论你是做图像处理入门学习,还是要在项目里实现贴纸、水印、实时滤镜,这篇文章都值得收藏。
1. overlay 是什么,能解决什么问题
1.1 从一张图盖在另一张图上说起
Overlay 直译过来是“覆盖、叠加”。在图像处理和计算机视觉领域,overlay 指的是将一张图像(前景)按照一定的规则放置到另一张图像(背景)上,形成一个新的合成画面。
举个最直观的例子:视频会议时,摄像头画面是背景,你的姓名标签或者公司 Logo 是前景,前景覆盖在背景的某个位置,这个过程就是 overlay。
如果只是简单地把前景贴上去,会有一个明显问题——前景是矩形图片,它的不透明区域和透明区域没有办法区分。比如你想在直播画面上加一个“点赞”按钮,按钮本身可能是圆形的,但图片文件是矩形的。如果不处理,矩形四角就会把直播画面挡住。
所以,专业一点的 overlay 一定会涉及两种机制:
- 指定叠加区域(ROI),只把前景放在背景的某个局部。
- 使用 alpha 通道或掩码,让前景图中不需要显示的部分“透过去”。
1.2 overlay 和 blend、mosaic 的区别
很多初学者会把 overlay 和图像融合(blend)、图像拼接(mosaic)混为一谈。这里做一个简单区分:
| 概念 | 含义 | 典型应用 |
|---|---|---|
| Overlay 叠加 | 将前景覆盖到背景的指定区域,不改变整张背景的亮度分布 | 水印、Logo、贴纸、文字标注 |
| Blend 融合 | 两张图按权重比例混合,产生半透明效果 | 幻灯片转场、曝光合成 |
| Mosaic 拼接 | 将多张图按空间位置拼接成一张大图 | 全景照片、地图拼接 |
一句话总结:overlay 关心的是“覆盖位置和覆盖内容”,blend 关心的是“混合权重”,mosaic 关心的是“空间对齐”。
本文重点讲 overlay,但在部分实战案例中会用到 blend 的基础公式。
1.3 overlay 的典型应用场景
Overlay 的应用范围非常广,这里列几个开发中最常见的:
- 相机实时贴纸:人脸识别后把帽子、眼镜贴到人脸上,这就是典型的 overlay 效果,也是“overlay 相机”类 App 的核心能力。
- 视频水印:给录屏或直播流打上时间戳、频道 Logo。
- 图像标注:在目标检测结果上叠加检测框、类别名称和置信度。
- UI 半透明弹层:前端开发里也有 overlay 概念,指覆盖在页面上的半透明遮罩层。
- 增强现实(AR):在真实场景上叠加虚拟模型或指示箭头。
可以看出,overlay 是图像处理领域非常基础但又非常高频的能力,掌握它之后,很多上层应用都可以基于它快速搭建。
2. 环境准备与版本说明
2.1 开发环境
本文示例代码基于 Python 和 OpenCV 实现。OpenCV 是目前图像处理领域使用最广泛的跨平台计算机视觉库,内置了大量图像运算函数,非常适合做 overlay 开发。
环境版本建议如下:
- 操作系统:Windows 10 / 11、Ubuntu 20.04 及以上、macOS 均可
- Python 版本:3.8 及以上
- OpenCV 版本:4.5 及以上
- 开发工具:VS Code、PyCharm 均可
如果你的电脑还没有安装 OpenCV,可以通过 pip 命令直接安装:
pip install opencv-python如果需要用到 OpenCV 的额外工具模块(比如人脸检测),可以再安装:
pip install opencv-contrib-python2.2 验证安装是否成功
安装完成后,打开 Python 交互环境或者写一个简单的脚本验证版本:
import cv2 print(cv2.__version__)如果能正常输出版本号,例如4.8.1,说明环境已经就绪。
这里需要提醒一下:不同 OpenCV 版本的部分函数签名和性能表现会有差异,本文示例代码以常见 4.x 版本为基准。如果你的版本较老,遇到 API 不兼容的问题,建议先升级版本。
2.3 测试图片准备
为了还原完整流程,建议准备两张图片:
- 一张作为背景图,建议用照片或视频帧,尺寸稍大。
- 一张作为前景图,最好是带透明通道的 PNG 图片,比如一个小图标或文字 Logo。
如果你手头没有合适的图,也可以用 OpenCV 直接创建一张纯色背景和一张画了形状的前景图,这样更容易控制实验变量。后面的实战案例会同时给出“创建测试图”和“读取真实图片”两种方式。
3. overlay 核心原理拆解
在写代码之前,我们先把 overlay 背后的原理理清楚。这一节的内容是后面所有案例的基础。
3.1 图像在计算机中的表示
计算机中的彩色图像通常用 RGB 三通道表示,每个通道的取值在 0 到 255 之间。对于带透明效果的图像,还会增加一个 alpha 通道,用 RGBA 表示。OpenCV 中默认使用 BGR 通道顺序,这一点和常规的 RGB 顺序不同,初学者经常会在这里踩坑。
一张宽度为 w、高度为 h 的图像,在 OpenCV 中的数据结构是一个形状为(h, w, 3)或(h, w, 4)的三维数组。其中:
- 第一维是高度(行数)
- 第二维是宽度(列数)
- 第三维是通道数
访问某个像素的代码是:
# 获取图像在 (x, y) 位置的 BGR 像素值 b, g, r = img[y, x]这里传入的顺序是先 y 后 x,和数学坐标系中的“先 x 后 y”相反,写代码时要注意。
3.2 直接覆盖法
最简单的 overlay 思路:把前景图的像素直接赋值给背景图的对应区域。
假设背景图是background,前景图是foreground,要放到背景的左上角,代码如下:
# 文件路径:demo_direct.py import cv2 # 读取背景图和前景图 background = cv2.imread("background.jpg") foreground = cv2.imread("foreground.png") # 获取前景图尺寸 fh, fw = foreground.shape[:2] # 直接将前景覆盖到背景的左上角 background[0:fh, 0:fw] = foreground cv2.imshow("overlay", background) cv2.waitKey(0) cv2.destroyAllWindows()这种方式最简单,但它有一个致命问题:如果前景图是矩形,它会完全遮挡背景区域,而且不支持透明效果。
3.3 Alpha 混合公式
要实现半透明或透明叠加,就需要用到 alpha 混合(Alpha Blending)。
Alpha 通道记录的是每个像素的不透明度,取值范围是 0 到 255。其中:
- 0 表示完全透明
- 255 表示完全不透明
- 中间值表示半透明
Alpha 混合的公式如下:
out = (foreground * alpha + background * (1 - alpha)) / 255这个公式的含义是:最终像素的颜色由前景色和背景色按 alpha 权重混合而成。alpha 越接近 255,前景越清晰;alpha 越接近 0,背景越明显。
OpenCV 中提供了一个现成的函数cv2.addWeighted,但它只能对整张图做固定权重的混合,不适合需要按像素 alpha 值动态混合的场景。所以我们通常在实战中自己实现像素级的 alpha 混合。
3.4 掩码(Mask)与位运算
在处理 overlay 时,掩码是一个非常重要的工具。
掩码是一张单通道图像,通常用 0 和 255 表示每一块区域是否参与运算。0 表示不参与,255 表示完全参与。
以“在背景图上叠加一个圆形”为例,如果直接把圆形图贴上去,矩形区域会遮挡背景。但如果先生成一个掩码:圆形内部是 255,外部是 0,然后用位运算把背景中被圆形覆盖以外的区域保留下来,再叠加圆形内容,就能实现完美的圆形贴图效果。
OpenCV 提供的常用位运算函数包括:
cv2.bitwise_and()按位与cv2.bitwise_or()按位或cv2.bitwise_not()按位取反
后面的实战案例会详细演示掩码的使用方式。
4. 完整实战:OpenCV 实现 overlay 全流程
下面进入代码实战环节。我们按照从简单到复杂的顺序,分 5 个案例讲解。
4.1 案例一:将整张前景图覆盖到背景中心
先看一个最基础的案例:将一张不透明的前景图覆盖到背景图中心。
思路:
- 读取背景图和前景图。
- 计算前景图在背景图中的放置坐标,使前景居中。
- 将前景图写入背景图的对应区域。
# 文件路径:demo_overlay_center.py import cv2 import numpy as np # 1. 读取图像 background = cv2.imread("background.jpg") foreground = cv2.imread("foreground.jpg") # 2. 获取尺寸 bg_h, bg_w = background.shape[:2] fg_h, fg_w = foreground.shape[:2] # 3. 计算居中坐标 x = (bg_w - fg_w) // 2 y = (bg_h - fg_h) // 2 # 确保坐标不小于 0 x = max(0, x) y = max(0, y) # 4. 覆盖 background[y:y + fg_h, x:x + fg_w] = foreground # 5. 显示结果 cv2.imshow("Overlay Center", background) cv2.waitKey(0) cv2.destroyAllWindows()运行结果会看到前景图完整出现在背景图正中间。
需要注意的关键点
- 如果前景图尺寸大于背景图,切片赋值会报错。所以实战中通常要加判断,或者用
cv2.resize先把前景图缩放到合适大小。 - 这里要求两张图的通道数一致,否则会出现广播错误。
4.2 案例二:ROI 区域叠加 Logo
在实际项目中,Logo 通常只放在角落,不会铺满整个画面。这时就需要通过 ROI(Region of Interest,感兴趣区域)来限定叠加范围。
以下代码把一个小型水印 Logo 放到背景图的右下角,并留出边距:
# 文件路径:demo_overlay_logo.py import cv2 background = cv2.imread("background.jpg") logo = cv2.imread("logo.png") bg_h, bg_w = background.shape[:2] logo_h, logo_w = logo.shape[:2] # 右下角位置,距离边缘各 20 像素 margin = 20 x = bg_w - logo_w - margin y = bg_h - logo_h - margin # 限制最小坐标 x = max(0, x) y = max(0, y) # 提取 ROI roi = background[y:y + logo_h, x:x + logo_w] # 将 Logo 覆盖到 ROI roi[:] = logo cv2.imshow("Logo Overlay", background) cv2.waitKey(0) cv2.destroyAllWindows()什么是 ROI
ROI 就是图像上我们关心的一个矩形子区域。在上面的例子中,background[y:y+logo_h, x:x+logo_w]就是从背景图中切出的一个和 Logo 尺寸一致的区域。
ROI 在图像处理中非常常用,因为很多操作只需要处理局部区域,而不需要对全图运算,这样可以显著提升性能。
4.3 案例三:带透明通道的 PNG 叠加
这是实际开发中最常见、也最容易被误解的场景。
带透明通道的 PNG 图片读取后是四通道(BGRA),而普通背景图是三通道(BGR)。如果把四通道图像直接赋给三通道区域,会出现通道数不匹配的问题。
正确的做法是:把前景图的 alpha 通道提取出来作为掩码,然后利用copyTo的原理手动实现带透明叠加。
OpenCV 中一种比较简洁的方案是使用cv2.copyTo,但它更常用于掩码场景。这里我们用更通用、更好理解的像素级混合来实现透明叠加:
# 文件路径:demo_overlay_alpha.py import cv2 import numpy as np # 读取背景和带透明通道的前景 background = cv2.imread("background.jpg") foreground = cv2.imread("foreground.png", cv2.IMREAD_UNCHANGED) # 检查前景是否为四通道 if foreground.shape[2] == 4: # 分离 BGR 和 Alpha 通道 fg_bgr = foreground[:, :, 0:3] alpha = foreground[:, :, 3] else: fg_bgr = foreground alpha = np.full((foreground.shape[0], foreground.shape[1]), 255, dtype=np.uint8) # 获取尺寸 bg_h, bg_w = background.shape[:2] fg_h, fg_w = fg_bgr.shape[:2] # 放到背景左上角 x, y = 50, 50 # 边界检查 if x + fg_w > bg_w: fg_w = bg_w - x fg_bgr = fg_bgr[:, :fg_w] alpha = alpha[:, :fg_w] if y + fg_h > bg_h: fg_h = bg_h - y fg_bgr = fg_bgr[:fg_h] alpha = alpha[:fg_h] # 提取 ROI roi = background[y:y + fg_h, x:x + fg_w] # 将 alpha 通道归一化到 0-1 alpha_f = alpha.astype(np.float32) / 255.0 # 扩展 alpha 到三通道,便于逐通道计算 alpha_3 = cv2.merge([alpha_f, alpha_f, alpha_f]) # 前景也转为浮点 fg_f = fg_bgr.astype(np.float32) roi_f = roi.astype(np.float32) # alpha 混合 blended = fg_f * alpha_3 + roi_f * (1 - alpha_3) blended = blended.astype(np.uint8) # 写回背景 background[y:y + fg_h, x:x + fg_w] = blended cv2.imshow("Alpha Overlay", background) cv2.waitKey(0) cv2.destroyAllWindows()这段代码做了什么
- 用
cv2.IMREAD_UNCHANGED读取完整通道,确保透明 PNG 的 alpha 通道被保留。 - 分离出 BGR 图像和 alpha 通道。
- 对 ROI 区域逐像素做 alpha 混合。
- 将混合结果写回背景。
为什么不能直接用 addWeighted
cv2.addWeighted适用于“全局固定权重”的混合,它不读取每个像素自己的 alpha 值。而透明 PNG 的每个像素透明度不一样,所以必须自定义混合逻辑。
很多初学者在这里踩坑,就是因为拿addWeighted强行合成透明 PNG,结果图片上的透明区域变成了黑色块。
4.4 案例四:图片素材生成测试图
如果没有现成的透明 PNG,可以用 OpenCV 的绘图函数快速创建一张测试图,方便验证叠加效果。
# 文件路径:demo_create_test_images.py import cv2 import numpy as np # 创建一张纯色背景图 background = np.zeros((480, 640, 3), dtype=np.uint8) background[:] = (200, 200, 200) # 浅灰色 # 创建一张带透明通道的前景图 # 高度 200,宽度 200,4 通道 BGRA foreground = np.zeros((200, 200, 4), dtype=np.uint8) # 在中央绘制一个实心圆(红色,不透明区域) cv2.circle(foreground, (100, 100), 80, (0, 0, 255, 255), thickness=-1) # 在另一个位置绘制一个半透明矩形(蓝色,alpha=128) cv2.rectangle(foreground, (40, 40), (160, 160), (255, 0, 0, 128), thickness=-1) # 保存图片 cv2.imwrite("background.jpg", background) cv2.imwrite("foreground.png", foreground) print("测试图片已生成")这张前景图同时包含完全不透明的红色圆形、半透明的蓝色矩形,非常适合用来直观理解 alpha 混合的效果。
4.5 案例五:相机实时 overlay(overlay 相机效果)
接下来进入本文的重头戏:结合摄像头实现实时画面叠加。这个场景在“overlay 相机”类应用中非常典型,比如在摄像头画面上叠加时间、水印或简单贴纸。
要实现实时叠加,需要在视频帧的循环中不断读取摄像头画面,并将前景内容叠加到每一帧上。为了减小波动,这里我们把叠加逻辑封装成函数。
# 文件路径:demo_camera_overlay.py import cv2 import numpy as np import time def overlay_transparent(background, foreground, x, y): """ 将带透明通道的前景图叠加到背景图的指定位置。 background: 背景图 (BGR) foreground: 前景图 (BGRA 或 BGR) x, y: 左上角坐标 """ fg_h, fg_w = foreground.shape[:2] bg_h, bg_w = background.shape[:2] # 越界处理 if x >= bg_w or y >= bg_h: return background # 裁剪前景,防止超出边界 if x + fg_w > bg_w: fg_w = bg_w - x foreground = foreground[:, :fg_w] if y + fg_h > bg_h: fg_h = bg_h - y foreground = foreground[:fg_h] # 如果有 alpha 通道则做透明混合,否则直接赋值 if foreground.shape[2] == 4: fg_bgr = foreground[:, :, 0:3] alpha = foreground[:, :, 3].astype(np.float32) / 255.0 alpha_3 = cv2.merge([alpha, alpha, alpha]) roi = background[y:y + fg_h, x:x + fg_w].astype(np.float32) fg_f = fg_bgr.astype(np.float32) blended = fg_f * alpha_3 + roi * (1 - alpha_3) background[y:y + fg_h, x:x + fg_w] = blended.astype(np.uint8) else: background[y:y + fg_h, x:x + fg_w] = foreground return background # 加载透明水印或贴纸 sticker = cv2.imread("sticker.png", cv2.IMREAD_UNCHANGED) if sticker is None: print("请准备一张贴纸图片:sticker.png") exit() # 打开摄像头 cap = cv2.VideoCapture(0) if not cap.isOpened(): print("无法打开摄像头") exit() print("按 Q 键退出实时叠加预览") while True: ret, frame = cap.read() if not ret: print("读取画面失败") break # 在画面左上角叠加贴纸 frame = overlay_transparent(frame, sticker, 30, 30) # 在画面右下角叠加当前时间 current_time = time.strftime("%Y-%m-%d %H:%M:%S") cv2.putText( frame, current_time, (frame.shape[1] - 320, frame.shape[0] - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA ) cv2.imshow("Camera Overlay", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()运行效果说明
- 摄像头画面正常显示。
- 贴纸叠加在画面左上角,且透明区域不会遮挡背景。
- 右上角会动态显示当前系统时间。
这个示例已经具备了一个“overlay 相机”雏形。如果要商用或做产品原型,可以在此基础上增加多张贴纸切换、拖拽移动、缩放、旋转等功能。
实时性能优化点
相机实时叠加对性能有较高要求。以下是一些实际项目中常用的优化手段:
- 降低处理分辨率:摄像头采集后先用
cv2.resize缩小到合适尺寸,叠加完成后再展示或编码。 - 缩小 ROI 运算范围:只对叠加区域做像素混合,不对全图处理。
- 减少浮点运算:尽可能使用整数运算或查表法,避免每帧生成浮点数组。
- 使用 C++ 版本:同样的逻辑 C++ 比 Python 快很多,生产环境可以考虑。
- 降低贴纸尺寸:贴纸越大,混合计算的像素数越多。
5. 常见问题与排查思路
在 overlay 开发中,有几个问题是我见到频率最高的,这里统一做一个排查清单。
5.1 叠加区域出现黑色背景
现象:透明 PNG 叠加到背景上后,原本透明的区域变成了黑色方块。
原因:常见的原因是直接把四通道 BGRA 图像赋值到三通道背景区域,alpha 通道没有被正确使用;另一种情况是用了cv2.addWeighted强行混合,透明区域被当作黑色像素。
解决思路:
- 用
IMREAD_UNCHANGED读取前景图,确认是否有 alpha 通道。 - 分离 alpha 通道,按像素做混合,而不是用固定权重。
- 检查前景图本身是否真的包含透明信息,很多从网上直接下载的“PNG”其实是白底或黑底的 JPG 改名。
5.2 图像通道数不匹配
现象:执行切片赋值时报错ValueError: could not broadcast input array from shape ... into shape ...。
原因:背景是三通道(BGR),前景是四通道(BGRA),通道数不一致。
解决思路:
- 如果不需要透明效果,用
cv2.cvtColor(foreground, cv2.COLOR_BGRA2BGR)去掉 alpha 通道。 - 如果需要透明效果,走 4.3 节的 alpha 混合流程。
5.3 叠加区域边缘有锯齿或白边
现象:圆形或异形贴纸边缘出现不自然的齿状、白边。
原因:前景图 alpha 通道边缘过渡不平滑,或者缩放操作使用了默认的最近邻插值。
解决思路:
- 在
cv2.resize时使用cv2.INTER_LINEAR或cv2.INTER_CUBIC插值。 - 对 alpha 通道做轻微的模糊平滑,比如高斯模糊。
- 贴纸设计时尽量保留 1-2 像素的半透明边缘过渡。
5.4 视频叠加出现卡顿
现象:摄像头实时叠加时画面明显卡顿,延迟严重。
原因:叠加逻辑过于复杂,每帧处理时间太长;或者没有控制摄像头采集帧率。
解决思路:
- 优化 ROI 范围,不要对全图做浮点混合。
- 降低处理分辨率。
- 将贴纸预先缩放到固定尺寸,避免每帧
resize。 - 检查摄像头
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)等参数,适当降低分辨率。
5.5 文字或贴纸叠加后不清晰
现象:叠加的文字或贴纸非常模糊,或者颜色偏淡。
原因:可能是 alpha 值设置过低,或者使用了浮点转换后精度丢失。
解决思路:
- 贴纸的 alpha 尽量使用 255,保持完全不透明。
- 如果需要半透明,建议 alpha 值不低于 128。
- 混合计算结果记得
np.clip(0, 255)后再转uint8。
6. 最佳实践与工程建议
6.1 封装通用 overlay 函数
不要在业务代码里散落大量叠加逻辑。建议将叠加功能封装成独立函数或工具类,方便复用和测试。
比如本文 4.5 节的overlay_transparent函数,就是一个最小可用的封装。实际项目中可以在此基础上增加:
- 支持旋转和缩放。
- 支持多个前景对象管理。
- 支持叠加优先级(z-index)。
- 支持坐标归一化,适配不同分辨率。
6.2 边界保护不可省略
叠加时最容易忽略的就是坐标越界问题。当用户拖动贴纸到画面边缘,或者摄像头分辨率改变时,如果没有边界保护,程序很容易崩溃。
建议在所有叠加函数的入口处做统一检查:
if x < 0 or y < 0: x, y = max(0, x), max(0, y) if x >= bg_w or y >= bg_h: return background6.3 合理使用浮点运算
Alpha 混合必然涉及浮点运算,但浮点运算比整型运算慢。在高性能场景下,可以考虑把 alpha 值预先做成查找表(LUT),避免每帧重复计算。
例如,alpha 通道取值只有 256 种,可以提前把alpha / 255.0和1 - alpha / 255.0两个结果存入数组,运行时直接查表。
6.4 数据与资源管理
- 贴纸等静态资源在初始化时加载一次,不要每帧读取。
- 视频帧用完即释放引用,避免内存持续增长。
- 摄像头使用完后一定调用
cap.release(),防止设备被占用。
6.5 安全与合规提示
如果 overlay 能力应用到相机类产品中,需要注意以下几点:
- 隐私合规:实时叠加数据不应在未授权的情况下上传或持久化。
- 内容安全:叠加的贴纸、文字内容需要经过审核,避免恶意内容。
- 误用防护:不要利用叠加功能伪造证件、截图或关键证据,涉及真实身份验证场景时要做好来源标记。
- 生产环境变更:如果叠加逻辑部署在线上服务中,修改前要在测试环境验证,做好灰度发布和回滚方案。
6.6 性能瓶颈分析
如果实时叠加仍然卡顿,建议先做性能分析,而不是盲目优化。可以使用cv2.getTickCount()统计每段逻辑的耗时:
t1 = cv2.getTickCount() # 叠加逻辑 frame = overlay_transparent(frame, sticker, 30, 30) t2 = cv2.getTickCount() time_ms = (t2 - t1) / cv2.getTickFrequency() * 1000 print(f"叠加耗时: {time_ms:.2f} ms")通过输出定位耗时最高的环节,再针对性优化。
7. 总结与下一步学习路线
本文从最基础的像素覆盖讲起,依次介绍了 ROI 区域叠加、Alpha 通道混合、透明 PNG 叠加,以及相机实时 overlay 的完整实现。重点解决了几类典型问题:
- 透明 PNG 叠加出现黑块。
- 通道数不匹配导致赋值失败。
- 实时叠加性能不足。
- 贴纸边缘锯齿处理。
如果你是想系统学习图像处理,下一步建议按以下路线推进:
- 熟悉 OpenCV 基础操作:图像读写、颜色空间转换、几何变换。
- 掌握掩码和位运算:
bitwise_and、bitwise_or、bitwise_not。 - 学习图像平滑与边缘检测,理解高斯模糊、Canny 等基础算法。
- 进阶学习图像融合与无缝克隆:
cv2.seamlessClone,它比普通 overlay 更自然。 - 结合深度学习目标检测,把检测框、关键点、分割结果叠加到图像上。
Overlay 是图像处理中很小的一块,但它串联了图像表示、像素操作、通道处理、性能优化等多个核心知识点。把这块打牢,后续无论是做相机类 App、视频处理工具,还是计算机视觉可视化,都会顺手很多。
如果本文对你有帮助,可以收藏备用。也欢迎在实际项目中遇到问题时回来对照排查清单快速定位。动手把代码跑一遍,比只看不练要有效得多。