AI-For-Beginners 计算机视觉入门:OpenCV 图像预处理、帧差分与光流的实战解析

发布时间:2026/10/9 1:42:58
AI-For-Beginners 计算机视觉入门:OpenCV 图像预处理、帧差分与光流的实战解析 教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载本文基于 AI-For-Beginners 课程第 06 课《Introduction to Computer Vision》原文档见 translations/fa/lessons/4-ComputerVision/06-IntroCV/README.md英文原版为 lessons/4-ComputerVision/06-IntroCV/README.md系统讲解在把图像送入神经网络之前如何先用经典算法增强图像从 Python 图像处理库选型、OpenCV 的图像加载与色彩空间转换到缩放、模糊、阈值化、透视变换等预处理操作再到帧差分运动检测与光流两大视频理解技术。读完本文你可以直接在仓库配套的 OpenCV.ipynb 中复现盲文符号切分与手背运动方向识别等完整流程。什么是计算机视觉任务版图与课程定位计算机视觉Computer Vision的目标是让计算机获得对数字图像的“高层理解”。这个定义相当宽泛因为“理解”可以指代多种具体任务目标检测Object Detection在图像中找到某个物体事件检测Event Detection理解画面中正在发生什么图像描述用自然语言文字描述一张图片3D 场景重建从图像重建三维场景与人脸相关的专门任务年龄与情绪估计、人脸检测与识别、3D 姿态估计等。其中最简单的任务之一是图像分类image classification。计算机视觉通常被视为人工智能的一个分支如今大多数计算机视觉任务都使用神经网络求解——本课程的下一课将专门讲解用于视觉任务的卷积神经网络lessons/4-ComputerVision/07-ConvNets/README.md。但本课的核心观点是在把图像交给神经网络之前很多情况下先用算法化非 AI的技术对图像做增强和预处理是明智的。这样做可以降低神经网络的任务难度从而用更少的训练数据解决问题——这一点在课程配套 Notebook 的总结中也被明确强调。Python 图像处理库选型imageio、Pillow、OpenCV、dlib原文档列出了四个常用于图像处理的 Python 库定位各有不同库定位与特点imageio用于读写不同图像格式支持 ffmpeg是“把视频帧转成图像”的实用工具Pillow又名 PIL能力稍强支持变形、调色板调整等图像操作OpenCVC 编写的强大图像处理库是图像处理的de facto标准提供便捷的 Python 接口dlibC 机器学习库实现了包括部分计算机视觉算法在内的众多算法同样有 Python 接口可用于人脸检测、面部关键点检测等挑战型任务从仓库根目录的 requirements.txt 可以看到课程环境对其中两个库做了固定版本imageio2.35.0与pillow12.2.0说明课程 Notebook 的图像读写依赖这两个库OpenCVcv2则需要在本地自行安装。本课选择 OpenCV 作为主线理由与原文档一致它包含大量用 C 实现的高效算法同时可以从 Python 直接调用。课程的目标不是“学完 OpenCV 全部功能”而是演示它在哪些环节适用、如何使用。OpenCV 基础图像加载与 BGR/RGB 色彩空间图像即 NumPy 数组Python 中图像可以用 NumPy 数组天然表示。以 320×200 像素的图像为例灰度图存储为形状200x320的二维数组彩色图存储为形状200x320x3的三维数组最后 3 维对应三个颜色通道。加载并显示一张图像的最小代码源自 OpenCV.ipynb 的 “Loading Images” 一节import cv2 import matplotlib.pyplot as plt im cv2.imread(image.jpeg) plt.imshow(im)注意数组形状是(高, 宽)而口语描述分辨率时习惯说“宽x高”两者容易混淆。BGR vs RGBOpenCV 的历史包袱OpenCV 传统上对彩色图像使用BGR蓝-绿-红编码而 Python 生态中其余工具如 matplotlib使用更常见的RGB红-蓝-蓝顺序。如果直接plt.imshow图像会呈现明显的“肤色发蓝”等颜色偏差。正确做法是转成 RGB 空间后再显示可用 NumPy 轴交换或调用 OpenCV 函数im cv2.cvtColor(im, cv2.COLOR_BGR2RGB)同一个cv2.cvtColor函数还能完成其他色彩空间转换例如转为灰度图cv2.COLOR_BGR2GRAY或 HSV色相-饱和度-明度空间——后者在光流可视化中会再次用到。逐帧读取视频除了静态图像OpenCV 还能逐帧读取视频文件。仓库在 lessons/4-ComputerVision/06-IntroCV/data/motionvideo.mp4 提供了一个运动演示视频Notebook 中的读取方式为vid cv2.VideoCapture(data/motionvideo.mp4) c 0 frames [] while vid.isOpened(): ret, frame vid.read() if not ret: break frames.append(frame) c 1 vid.release() print(fTotal frames: {c})每个frame就是一个(H, W, 3)的 NumPy 数组后续所有“对数组做运算”的技巧都建立在这个表示之上。OpenCV 图像预处理工具箱在进入具体案例前先完整梳理原文档给出的预处理能力清单这些都是送入神经网络前可以施加的步骤缩放im cv2.resize(im, (320,200), interpolationcv2.INTER_LANCZOS)模糊im cv2.medianBlur(im, 3)中值滤波或im cv2.GaussianBlur(im, (3,3), 0)高斯模糊亮度与对比度调整通过 NumPy 数组运算直接完成阈值化调用cv2.threshold/cv2.adaptiveThreshold文档明确指出这通常比手动调亮度对比度更可取几何变换仿射变换Affine当你需要组合旋转、缩放、错切并且知道图像中三对源/目标点位置时使用仿射变换保持平行线平行透视变换Perspective当你知道四对源/目标点位置时使用。典型场景用手机从某个角度拍一张矩形文档的照片希望还原出文档本身的正视图光流Optical Flow用于理解图像内部的运动。实战案例一盲文书籍照片的预处理与符号切分这是 OpenCV.ipynb 中最完整的案例给定一张盲文书籍照片 data/braille.jpeg目标是把每个独立的盲文点字符号切分出来供后续神经网络逐个分类类似 MNIST 单字符图像。处理链路分为四步每一步都对应前面工具箱里的一项技术第 1 步阈值化增强。转灰度后先用模糊 自适应阈值 中值滤波 Otsu 全局阈值 高斯模糊的“双阈值”组合把点阵从背景中干净地分离出来im cv2.blur(bw_im, (3,3)) im cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 5, 4) im cv2.medianBlur(im, 3) _, im cv2.threshold(im, 0, 255, cv2.THRESH_OTSU) im cv2.GaussianBlur(im, (3,3), 0) _, im cv2.threshold(im, 0, 255, cv2.THRESH_OTSU)第 2 步特征点检测。用 ORB 检测器把每个“点”识别为特征点得到全部点字的坐标集合orb cv2.ORB_create(5000) f, d orb.detectAndCompute(im, None) pts [x.pt for x in f]第 3 步透视变换校正。由所有特征点的坐标求最小/最大包围盒对文本区域做透视校正cv2.findHomographycv2.warpPerspective使可能倾斜的文字变成水平对齐的矩形src_pts np.array([(min_x-off, min_y-off), (min_x-off, max_yoff), (max_xoff, min_y-off), (max_xoff, max_yoff)]) w int(max_x - min_x off*2) h int(max_y - min_y off*2) dst_pts np.array([(0,0), (0,h), (w,0), (w,h)]) ho, m cv2.findHomography(src_pts, dst_pts) trim cv2.warpPerspective(im, ho, (w, h))第 4 步固定网格切片。对齐后的图像按固定字符尺寸char_h36,char_w24遍历网格跳过全空窗口逐个产出符号图像char_h 36 char_w 24 def slice(img): dy, dx img.shape y 0 while y char_h dy: x 0 while x char_w dx: if np.max(img[y:ychar_h, x:xchar_w]) 0: # 跳过空白格 yield img[y:ychar_h, x:xchar_w] x char_w y char_h处理结果如下从原始盲文照片到预处理后的点阵图再到逐个切分出的符号序列图片均出自 OpenCV.ipynb 的运行输出Notebook 在此给出的结论值得记住这些全部是纯图像处理没有任何 AI 参与当计算机视觉能把神经网络的工作做简单时就应该这样做因为这意味着可以用更少的训练数据解决问题。实战案例二帧差分Frame Difference运动检测监控场景下“发生了什么”比“画面是什么”更值得第一时间知道。如果相机固定连续帧应当非常相似由于帧就是数组直接做减法即可得到像素级差异——静止帧差异小画面中出现明显运动时差异变大。OpenCV.ipynb 中的实现分四步1. 灰度化 逐帧差分并统计“活动量”bwframes [cv2.cvtColor(x, cv2.COLOR_BGR2GRAY) for x in frames] diffs [(p2 - p1) for p1, p2 in zip(bwframes[:-1], bwframes[1:])] diff_amps np.array([np.linalg.norm(x) for x in diffs]) plt.plot(diff_amps)每个diff_amps[i]是相邻两帧差值矩阵的 L2 范数数值越高代表变化越剧烈。2. 滑动平均去噪 阈值线def moving_average(x, w): return np.convolve(x, np.ones(w), valid) / w threshold 13000 plt.plot(moving_average(diff_amps, 10)) plt.axhline(ythreshold, colorr, linestyle-)3. 用np.where找出超过阈值的帧并用subsequence提取长度大于 30 帧的连续活动段即一次“事件”active_frames np.where(diff_amps threshold)[0] def subsequence(seq, min_length30): ss [] for i, x in enumerate(seq[:-1]): ss.append(x) if x 1 ! seq[i1]: if len(ss) min_length: return ss ss.clear()4. 展示事件中间帧。这里正好暴露了 BGR/RGB 问题——直接plt.imshow(frames[mid])会颜色发怪需要cv2.cvtColor(frames[mid], cv2.COLOR_BGR2RGB)修正。下面的图展示了视频帧与对应帧差分的对比左半为原始帧右半为相邻帧之差运动区域的亮部即变化集中处这一方案的工程价值在于成本低先用廉价的帧差分判断“有事发生”再决定是否唤醒昂贵的神经网络做进一步分析。实战案例三光流Optical Flow——不仅知道“动了”还知道“往哪动”帧差分只能给出变化的“量”无法回答“哪里在动、朝哪个方向动”。光流技术解决的就是这个问题分两种稠密光流Dense Optical Flow计算矢量场给出每一个像素的去向稀疏光流Sparse Optical Flow选取图像中若干显著特征如边缘逐帧追踪它们的轨迹。OpenCV.ipynb 用 Farneback 算法计算稠密光流flows [cv2.calcOpticalFlowFarneback(f1, f2, None, 0.5, 3, 15, 3, 5, 1.2, 0) for f1, f2 in zip(bwframes[:-1], bwframes[1:])]每个 flow 的形状与帧相同、带 2 个通道分别对应光流矢量的 x、y 分量。由于二维矢量场难以直接观察Notebook 用了一个巧妙的可视化技巧把光流转换到极坐标得到每个像素的“方向 强度”再映射到 HSV 色彩空间——色相Hue编码方向、明度Value编码强度、饱和度固定为 255def flow_to_hsv(flow): hsvImg np.zeros((flow.shape[0], flow.shape[1], 3), dtypenp.uint8) mag, ang cv2.cartToPolar(flow[..., 0], flow[..., 1]) hsvImg[..., 0] 0.5 * ang * 180 / np.pi hsvImg[..., 1] 255 hsvImg[..., 2] cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) return cv2.cvtColor(hsvImg, cv2.COLOR_HSV2BGR)渲染出来的运动帧中偏绿色对应向左移动偏蓝色对应向右移动运动强度越亮越明显光流还能用于推断整体运动趋势如果一帧内几乎所有像素都朝同一方向移动很可能发生的是相机本身的移动可以做补偿处理。课后实验用手背运动方向识别练习光流本课的配套实验位于 lessons/4-ComputerVision/06-IntroCV/lab/README.md给定一段视频中手掌在静止背景上向左/右/上/下移动的材料 palm-movement.mp4目标是用光流判定视频的哪些片段包含上/下/左/右方向的运动。起步 Notebook 为 MovementDetection.ipynb从源码结构看它留空了 4 个代码单元分别对应四个递进步骤按本课讲义的方式读取视频帧计算稠密光流并转换到极坐标方向 强度为每帧光流构建方向直方图——统计落入各角度 bin 的矢量数量从而在图上分离出不同的运动方向。Notebook 提示可以把模长低于某阈值的矢量清零以滤除眼睛、头部等微小运动的干扰观察直方图选取对应上/下/左/右方向的 bin 并判断是否超过阈值即可得出每个片段的主导运动方向。进阶目标Stretch goal结合肤色检测真正追踪手掌/手指的运动这已超出本课范围属于 dlib 等库擅长的挑战型任务。总结本课传达的核心经验是相对复杂的任务如运动检测、指尖检测有时可以纯粹靠计算机视觉技术解决不一定要动用神经网络。掌握 OpenCV 这类库的基本能力——图像加载与色彩空间转换、阈值化、特征点检测、透视变换、帧差分、光流——能让你在两大层面受益一是独立解决不需要模型的轻量任务二是在必须用模型时用预处理显著降低神经网络的负担、减少所需训练数据。按课程安排的顺序接下来应在 07-ConvNets 一课中学习把这些预处理后的图像送进卷积网络进行分类的完整链路若需要进一步深入光流可沿原文档给出的 OpenCV 官方教程与 LearnOpenCV 教程见英文原文档 lessons/4-ComputerVision/06-IntroCV/README.md 中的参考链接继续研读。赞分享教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载相关推荐AI for Beginners 计算机视觉入门OpenCV 图像预处理、帧差法运动检测与光学流实战AI for Beginners 计算机视觉入门OpenCV 图像预处理、帧差法运动检测与光学流实战 本文基于 AI for Beginners 课程中计算教程人工智能机器学习深度学习AI for Beginners 第 6 课计算机视觉入门 —— 用 OpenCV 做图像预处理、帧差运动检测与光流分析AI for Beginners 第 6 课计算机视觉入门 —— 用 OpenCV 做图像预处理、帧差运动检测与光流分析 导读 计算机视觉Computer教程人工智能机器学习深度学习AI for Beginners 计算机视觉入门用 OpenCV 完成图像预处理、运动检测与光流实战AI for Beginners 计算机视觉入门用 OpenCV 完成图像预处理、运动检测与光流实战 本篇基于 AI for BeginnersAI For教程人工智能机器学习深度学习上一篇alpaca.cpp技术债务清理代码重构与架构优化下一篇Knockout.js与Firebase云存储安全保护用户上传文件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询