计算机视觉算法工程师面试核心考点精讲

📅 2026/7/13 14:46:21 👁️ 阅读次数 📝 编程学习
计算机视觉算法工程师面试核心考点精讲

1. 传统图像处理核心考点

传统图像处理是计算机视觉的基础,掌握这些算法能让你在面试中展现出扎实的功底。我当年面试时被问得最多的就是边缘检测,面试官特别喜欢让候选人对比不同算子的特点。

1.1 边缘检测算法精要

Canny算子绝对是面试中的高频考点,它的五步流程需要烂熟于心:

  1. 高斯滤波去噪(σ=1.4的5x5核)
  2. Sobel算子计算梯度(建议手写Sobel的x/y方向卷积核)
  3. 非极大值抑制(NMS)细化边缘
  4. 双阈值检测(典型高低阈值比3:1)
  5. 边缘连接(DFS或BFS实现)
# OpenCV实现示例 import cv2 img = cv2.imread('test.jpg', 0) edges = cv2.Canny(img, 50, 150) # 阈值设置很关键

Sobel与Prewitt的区别在于卷积核权重:

  • Sobel的x方向核:[[-1,0,1], [-2,0,2], [-1,0,1]]
  • Prewitt更均匀:[[-1,0,1], [-1,0,1], [-1,0,1]]

Laplacian算子是二阶微分算子,对噪声敏感但能检测细边缘。有个经典面试题:为什么LoG(Laplacian of Gaussian)要先高斯模糊?答案是为了抑制噪声干扰。

1.2 图像滤波实战技巧

中值滤波去除椒盐噪声效果最好,但要注意:

  • 窗口大小取奇数(3x3, 5x5)
  • 时间复杂度O(n²k²),大图需要优化
// 手写中值滤波核心代码 uchar medianFilter(Mat src, int x, int y, int ksize) { vector<uchar> pixels; for(int i=-ksize/2; i<=ksize/2; ++i) for(int j=-ksize/2; j<=ksize/2; ++j) pixels.push_back(src.at<uchar>(y+i,x+j)); sort(pixels.begin(), pixels.end()); return pixels[pixels.size()/2]; }

高斯滤波的σ值决定平滑程度,σ越大核越大。实际工程中常用可分性优化,将二维卷积拆分为两次一维卷积,计算量从O(k²)降到O(2k)。

1.3 形态学操作本质

膨胀和腐蚀是形态学基础,面试常考开闭运算:

  • 开运算(先腐蚀后膨胀)去小噪点
  • 闭运算(先膨胀后腐蚀)填小孔洞

结构元素选择有讲究:

  • 矩形核适合直角边缘
  • 圆形核各向同性
  • 十字形核适合细长结构

2. 特征提取与描述子

2.1 SIFT算法详解

SIFT的四大步骤是必考题:

  1. 尺度空间构建(高斯金字塔+DoG)
  2. 关键点定位(泰勒展开修正位置)
  3. 方向分配(36bin梯度直方图)
  4. 描述子生成(4x4x8=128维向量)

面试陷阱:为什么SIFT具有尺度不变性?因为通过DoG极值检测找到了特征尺度。

2.2 ORB特征高效实现

ORB=FAST关键点+BRIEF描述子+方向补偿:

  • FAST检测速度快但噪声敏感
  • BRIEF用256bit二进制串,汉明距离计算快
  • 用灰度质心法计算方向提升旋转鲁棒性
# ORB特征匹配示例 orb = cv2.ORB_create() kp1, des1 = orb.detectAndCompute(img1, None) bf = cv2.BFMatcher(cv2.NORM_HAMMING) matches = bf.match(des1, des2)

2.3 HOG特征工程细节

HOG用于行人检测的经典实现:

  1. 图像归一化(Gamma+颜色归一化)
  2. 计算梯度([-1,0,1]核)
  3. 8x8细胞单元统计9bin直方图
  4. 16x16块归一化(L2-Hys)
  5. 串联所有块特征

注意:HOG对局部几何变化敏感,但对光照变化鲁棒。

3. 深度学习核心模型

3.1 CNN架构演进脉络

从LeNet到EfficientNet的进化路线:

  • LeNet5(1998):首个成功CNN,2卷积+3全连接
  • AlexNet(2012):ReLU+Dropout+数据增强
  • VGG(2014):小卷积堆叠,感受野等效大卷积
  • ResNet(2015):残差连接解决梯度消失
  • MobileNet(2017):深度可分离卷积降参数量

面试高频题:为什么ResNet有效?残差学习让梯度直接回传,缓解了深度网络退化问题。

3.2 目标检测算法对比

Two-stage vs One-stage本质区别:

  • Faster R-CNN:RPN生成候选框+ROI Pooling
  • YOLOv3:网格预测bbox+置信度+类别
  • SSD:多尺度特征图预测,平衡速度精度
# YOLOv3输出解析示例 def process_output(output, conf_thresh): boxes = output[..., :4] # xywh conf = output[..., 4:5] cls_probs = output[..., 5:] scores = conf * cls_probs keep = scores > conf_thresh return boxes[keep], scores[keep]

3.3 语义分割关键技术

FCN开创端到端分割,关键改进:

  • 全卷积替换全连接
  • 反卷积上采样
  • 跳跃连接融合深浅特征

U-Net的编码器-解码器结构:

  • 下采样路径捕获上下文
  • 上采样路径精确定位
  • 跨层连接恢复空间信息

4. 模型优化与部署

4.1 过拟合解决方案

实际项目中我用过的组合拳:

  1. 数据增强(旋转/翻转/色彩抖动)
  2. L2正则化(λ=0.001)
  3. Dropout(p=0.5)
  4. Early Stopping(验证集loss不降即停)
  5. Label Smoothing(ε=0.1)

注意:BN层也有轻微正则化效果,但不要依赖它来防止过拟合。

4.2 模型量化实战

TensorRT量化步骤:

  1. 校准:用代表性数据统计激活分布
  2. 量化:FP32转INT8(饱和量化)
  3. 部署:加载量化后的引擎推理
// TensorRT构建器配置 builder->setMaxBatchSize(1); config->setFlag(BuilderFlag::kINT8); config->setInt8Calibrator(calibrator);

4.3 部署优化技巧

我优化YOLOv5部署的经验:

  • 使用NMS优化(Merge NMS)
  • 半精度推理(FP16)
  • 图优化(层融合、常量折叠)
  • 内存池复用减少分配开销

在Jetson上实测,经过优化后推理速度从15FPS提升到45FPS,内存占用减少40%。