资讯详情

计算机视觉工程实践:从图像处理到检测分割的关键假设

📅 2026/10/29 13:21:21 | 华诺云谱 👁 阅读
计算机视觉工程实践:从图像处理到检测分割的关键假设
简介这份PDF面向计算机视觉入门者、相关专业学生与需要梳理CV知识框架的开发者围绕图像数据如何被感知、理解和解释展开帮助读者把零散概念串成从图像获取、前期处理、特征提取、图像分析到图像解释的完整流程。内容还覆盖图像分类、物体检测、图像分割、场景理解、人脸识别、姿态估计、光流估计与立体视觉等基本任务并结合图像搜索、自动标记、视觉监控、医学图像识别、自动驾驶和农业图像分析等应用场景说明技术落点对LeNet-5、AlexNet、VGGNet、GoogLeNet、ResNet等常用模型亦有提及便于建立算法脉络。资源包为1个PDF文件约483KB篇幅精炼适合通勤或课间快速通读并作为复习提纲。目前已有175人学习下载可作为课程预习、面试前概念梳理或项目选型时快速查阅的轻量资料。1. 计算机视觉的难点不在模型大小在那些被默认成立的假设很多人第一次接触计算机视觉会默认它的难度曲线跟模型参数量成正比觉得网络堆深、数据堆多识别效果自然上去。真到工程里会撞上一个反直觉的事实同一套 ResNet 权重换一个曝光条件、换一个相机镜头准确率能掉二十个点以上。问题不在网络而在网络看到的那张图——图像获取时的噪声、镜头畸变、白平衡漂移早在推理之前就把可用的信息破坏了。计算机视觉真正要处理的事不是让机器看见而是把看见拆成一串能被计算、能被验证的假设亮度怎么归一化、边缘怎么定义、像素之间的相似性怎么度量、运动在什么条件下守恒。这些假设一旦不成立再深的网络也只是在拟合噪声。搞懂这些假设的边界比多背几个网络结构有用得多。2. 图像管线与卷积网络从像素到特征的每一层都在丢信息计算机视觉的基本步骤在文档里被列成图像获取、前期处理、特征提取、图像分析、图像解释五步看着像流水账实际上每一步都是一次有损变换。理解这条管线重点不是记住顺序而是搞清楚每一步在丢什么信息、为什么必须丢、丢了之后还能不能补救。后面的卷积网络之所以能取代手工特征本质上也是因为它把这套丢信息的规则从人手里拿走了。2.1 图像获取和预处理校正、去噪、增强不是走过场图像获取这一步硬件决定了信息的上限。传感器的动态范围、镜头的畸变系数、快门的曝光时间在按下的那一刻就把场景压缩成了一个固定位深的矩阵。常见的实现思路是先做相机标定用棋盘格标出内参焦距、主点、畸变系数和外参把畸变校正掉再谈后面的处理。校正这件事很多人觉得只是让直线变直实际上它改变的是像素坐标和物理世界的映射关系后面但凡涉及几何测量——测距、定位、三维重建——都建立在它准确的前提上。预处理里另一件常被低估的事是去噪。图像噪声通常分成两类传感器热噪声近似高斯分布传输或坏点造成的是椒盐噪声。高斯噪声用线性滤波压椒盐噪声用中值滤波压选错了滤波器比不滤波更糟。给个能直接跑的对照import cv2 img cv2.imread(frame.jpg) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 大部分传统特征只用亮度通道 # 高斯滤波对零均值高斯噪声有效核越大越平滑但边缘也会糊 gaussian cv2.GaussianBlur(gray, (5, 5), sigmaX1.2) # 中值滤波对椒盐噪声有效非线性能保住边缘 median cv2.medianBlur(gray, 5) # 直方图均衡化把像素分布拉平缓解整体曝光偏暗或偏亮 equalized cv2.equalizeHist(median)参数上GaussianBlur 的核大小必须是奇数sigmaX 控制权重衰减sigma 越大邻域内参与加权的像素越多medianBlur 的 5 是窗口边长窗口越大去椒盐越彻底但细节丢得越多equalizeHist 只对单通道生效彩色图要先转色彩空间、只对亮度通道做否则色相会偏。这三行代码的顺序也有讲究——先去噪再均衡否则均衡化会把噪声一起放大成明显的斑块。前置处理之后图像增强做的事情是让后续算法想找的东西更明显。对比度拉伸、锐化、Gamma 校正都属于这一类但它们没有统一的最优解。增强过度会把噪声一起放大边缘检测就会在噪声上响应这在低照度监控里是血泪教训调参时看着边缘很清晰上线后满屏都是虚假轮廓。2.2 特征提取手工算子和卷积核差在哪传统特征提取靠人设计算子。边缘用 Sobel、Prewitt 这类一阶差分算子本质是在局部窗口里做加权求和权重一侧为正一侧为负响应大的地方就是灰度变化剧烈的地方。Canny 在此基础上加了三步高斯平滑、沿梯度方向的非极大值抑制、双阈值滞后连接所以它能给出细而连续的边缘。纹理特征常用 LBP局部二值模式和灰度共生矩阵颜色特征常用直方图这些特征的设计都带着明确的先验——人知道什么样的模式值得描述。这些手工特征的共同问题是它们编码的是人认为重要的东西。SIFT 对尺度和旋转不变是因为设计者显式地构造了高斯差分金字塔和主方向归一化但换个任务比如区分猫和狗边缘和角点未必是判别性最强的信息。手工特征的上限取决于设计者对任务的理解程度。卷积核把这件事反过来了。一个 3×3 卷积在图像上滑动做的运算和 Sobel 是同一类——局部加权求和——但权重不是人给的是反向传播学出来的。堆叠多层之后浅层卷积响应边缘和颜色斑块中层组合成纹理和部件深层响应语义对象这个层次结构不是设计出来的是优化过程自然形成的。这也是为什么 CNN 在图像分类上取代手工特征不是算子更聪明是特征的选择权交给了数据。代价是数据依赖。手工特征在小样本、低算力场景仍然有位置比如工业质检里缺陷模式固定一个阈值加形态学操作可能比训练网络更快更稳。这不是怀旧是工程上的性价比判断——数据标注成本远高于算法实现成本时传统方法反而更实际。2.3 从 LeNet-5 到 ResNet深度网络在拟合什么LeNet-5 是最早跑通手写数字识别的卷积网络之一结构很朴素卷积、池化、卷积、池化、全连接、softmax。它的意义在于确立了局部感受野 权值共享 空间下采样这套范式后面的网络都是在这套骨架上改。AlexNet 的贡献更多在工程侧ReLU 缓解梯度消失、Dropout 抑制过拟合、数据增强扩大样本把 ImageNet 上的错误率往下压了一大截。VGGNet 把大卷积核全换成 3×3 堆叠两个 3×3 的感受野等于一个 5×5但参数更少、非线性更多这个思路后来成了默认做法。GoogLeNet 的 Inception 模块用 1×1 卷积先降维再并行做不同尺寸的卷积把参数量压下来的同时拓宽了每层的感受野。ResNet 要解决的是另一个问题网络加深到一定程度训练误差不降反升。这不是过拟合是退化——深层网络至少应该能学到恒等映射但优化器在多层非线性变换里很难把恒等映射学出来。残差连接的做法是把目标从学 H(x)改成学 F(x) H(x) - x前向时把输入直接加到输出上import torch import torch.nn as nn class ResidualBlock(nn.Module): def __init__(self, channels): super().__init__() # 3x3 卷积维持空间尺寸biasFalse 是因为后面接了 BN self.conv1 nn.Conv2d(channels, channels, 3, padding1, biasFalse) self.bn1 nn.BatchNorm2d(channels) self.conv2 nn.Conv2d(channels, channels, 3, padding1, biasFalse) self.bn2 nn.BatchNorm2d(channels) self.relu nn.ReLU(inplaceTrue) def forward(self, x): identity x # 恒等分支不经过任何卷积 out self.relu(self.bn1(self.conv1(x))) out self.bn2(self.conv2(out)) out out identity # 残差相加梯度可绕过卷积层直接回传 return self.relu(out)关键在于反向传播时梯度沿着 identity 这条捷径可以直接流到浅层不用穿过两层卷积的链式乘积梯度消失被大幅缓解。另一个隐含的好处是网络可以很容易地学出什么都不做也就是 F(x) 趋近于零这让加深网络至少不会变差。注意第一个卷积前的输入通道数和 channels 不一致时identity 需要再加一个 1×1 卷积做投影否则形状对不上——这是实现上最常见的翻车点。这一节的代码不需要真的跑看懂数据形状的变化就够了输入通道数决定卷积核的深度padding 决定空间尺寸是否保持BN 放在卷积和激活之间是为了稳定每层的输入分布。理解这三件事再看任何现代骨干网络都不会迷路。3. 检测与分割从边界框到像素级标签多出来的那一步难在哪图像分类输出一个类别检测输出类别加位置分割输出每个像素的类别。每多一层输出就多一层监督信号和一组需要后处理的几何约束。很多项目在分类上跑通了迁移到检测就开始延期原因不是网络不会搭而是没意识到多出来的那一步改变的是整个问题的结构——分类的损失只看一个标签检测的损失要同时管分类置信度和四个坐标的回归两者的尺度差了几个数量级训练时得用不同的权重去平衡。3.1 检测的五步流水线候选区域、分类、回归和 NMS常见的实现思路分五步。第一步特征提取和分类网络共用骨干第二步生成候选区域早期用滑动窗口穷举后来用选择性搜索按颜色和纹理相似度合并超像素再往后 RPN 直接在特征图上用锚框回归出前景区域第三步对每个候选区域做分类判断里面是不是目标第四步位置回归把候选框往真实框上拉第五步后处理用非极大值抑制去掉重叠框。NMS 的逻辑很直接按置信度排序取最高的框把和它 IoU 超过阈值的框全部抑制掉重复到没有框为止。import numpy as np def nms(boxes, scores, iou_threshold0.5): boxes: [N, 4]格式 x1,y1,x2,y2scores: [N] order scores.argsort()[::-1] # 按置信度从高到低 keep [] while order.size 0: i order[0] keep.append(i) if order.size 1: break # 计算当前框和剩余所有框的交集 xx1 np.maximum(boxes[i, 0], boxes[order[1:], 0]) yy1 np.maximum(boxes[i, 1], boxes[order[1:], 1]) xx2 np.minimum(boxes[i, 2], boxes[order[1:], 2]) yy2 np.minimum(boxes[i, 3], boxes[order[1:], 3]) w np.maximum(0.0, xx2 - xx1) h np.maximum(0.0, yy2 - yy1) inter w * h area_i (boxes[i, 2] - boxes[i, 0]) * (boxes[i, 3] - boxes[i, 1]) area_o (boxes[order[1:], 2] - boxes[order[1:], 0]) * (boxes[order[1:], 3] - boxes[order[1:], 1]) iou inter / (area_i area_o - inter) # 只保留 IoU 低于阈值的框进入下一轮 order order[1:][iou iou_threshold] return keepiou_threshold 是唯一的可调项调低会更激进地删框密集场景人群、货架商品容易把挨着的目标误删调高会留下大量重叠框后处理压力大。这也是检测系统里最需要按场景调的参数之一没有通用值。工程里通常换成按类别分别抑制的版本避免不同类别的框互相压制——比如一个行人的框和一个背包的框重叠按类别分开抑制才不会把背包误删。这里还有个容易忽略的细节NMS 之前要做置信度过滤但过滤阈值和 NMS 阈值是联动的。把置信度阈值调低会让更多低分框进入 NMS重叠的假框反而可能把真框挤掉。这两个参数必须一起调单独调一个大概率翻车。3.2 分割的五条路线阈值、区域、边缘、图割和深度学习分割比检测更细检测给框分割给每个像素的标签。文档里列了五条路线它们的复杂度是递增的适用场景也不同。基于阈值是最老的一路。假设目标和背景在灰度上有明显差异找一个阈值把像素分成两类。Otsu 法把阈值选择变成一个优化问题遍历所有阈值计算前景和背景的类间方差取使方差最大的那个。它的前提是直方图呈双峰光照均匀。import cv2 img cv2.imread(scene.jpg, cv2.IMREAD_GRAYSCALE) # Otsu 自动选阈值第一个返回值是选中的阈值 thresh, binary cv2.threshold(img, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) print(自动选出的阈值:, thresh)参数上第二个参数 0 在 Otsu 模式下会被忽略255 是最大值标志位组合决定自动阈值和二值化方式。Otsu 在双峰明显的图上几乎不需要调参但遇到光照渐变或目标占比很小就会失效——目标只占几个像素时类间方差被背景主导阈值会偏向背景。基于区域的方法靠相似性和连通性。区域生长从一个种子点出发把灰度或颜色接近的邻域像素并进来分水岭把灰度图看成地形灰度值是海拔从局部极小值注水水汇合的地方就是边界均值漂移在色彩空间里做密度估计把收敛到同一模点的像素归为一类。这类方法对种子点和尺度敏感参数没调好会过分割或欠分割而且后处理合并小区域往往比分割本身更费时间。基于边缘的方法先用 Canny 或 Sobel 取出边缘再按边缘闭合性拼出轮廓。它适合轮廓清晰、背景干净的场景边缘断裂时会漏掉区域噪声多时会碎成一片。实际使用中通常要接一个形态学闭运算把断开的边缘连起来否则得到的是大量碎片而不是目标。基于图割的方法把分割变成图上的最小割问题。每个像素是节点相邻像素之间的相似性是边权再加两个虚拟终端节点表示前景和背景最小割把图分成两部分割边对应的就是分割边界。GrabCut 是这一类里最常被提到的实现用户画一个框框外肯定是背景框内用高斯混合模型迭代估计前景和背景的颜色分布。它的计算量比阈值法大得多但对复杂场景更稳代价是需要交互或者一个还算准确的初始框。基于深度学习的方法把分割变成逐像素分类。全卷积网络把分类网络的全连接层换成卷积层输出和输入同尺寸的特征图每个位置对应一个像素的类别。U-Net 加了编码器到解码器的跳跃连接把浅层的高分辨率特征拼回深层边缘更准。Mask R-CNN 在检测框内做像素级分割把检测和分割合到一个框架里。这一路本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑