引言
计算机视觉(CV)是 AI 最成熟的落地领域之一:
- 手机人脸解锁
- 自动驾驶识别行人和车辆
- 医学影像辅助诊断
- 电商以图搜图
- 短视频滤镜和特效
所有这些技术的底层都是图像处理。这篇文章从像素开始,带你走完”传统图像处理 → 深度学习特征提取 → CV 任务全景”的完整路径。
前置知识
看完 CNN 那篇再来,效果好一倍。
一、图像在计算机中的表示
1.1 一张图片 = 一个三维数组
1 2 3
| 灰度图 (Grayscale): [H×W] — 每个像素 0-255 的亮度值 彩色图 (RGB): [H×W×3] — 三个通道:红/绿/蓝 RGBA 图: [H×W×4] — 多一个 Alpha(透明度)
|
像素值范围通常是 0-255(8 位),深度学习会归一化到 0-1 或 -1~1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import cv2 import matplotlib.pyplot as plt import numpy as np
img = cv2.imread('example.jpg') img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
print(f"图片形状: {img_rgb.shape}") print(f"数据类型: {img_rgb.dtype}") print(f"像素范围: [{img_rgb.min()}, {img_rgb.max()}]")
plt.imshow(img_rgb) plt.axis('off') plt.show()
|
1.2 颜色空间
1 2 3 4 5 6 7 8
| gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
|
为什么需要多种颜色空间?
- RGB:显示器友好,但对光照敏感
- HSV:做颜色分割最好用(比如检测红色物体)
- LAB:计算颜色差异时最准确
二、传统图像处理操作
虽然深度学习已经替代了很多传统方法,但这些基础操作用来预处理数据、理解原理仍然很重要。
2.1 滤波与去噪
1 2 3 4 5 6 7 8 9 10 11
| blurred = cv2.blur(img, (5, 5))
gaussian = cv2.GaussianBlur(img, (5, 5), sigmaX=1.0)
median = cv2.medianBlur(img, 5)
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
|
2.2 边缘检测
1 2 3 4 5 6 7
| edges = cv2.Canny(img, threshold1=100, threshold2=200)
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3) sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3) sobel_mag = np.sqrt(sobel_x**2 + sobel_y**2)
|
Canny 边缘检测的效果:(想象一下一张图片变成线稿的效果)
1 2 3 4 5 6
| 原图 → Canny 边缘 ┌─────────┐ ┌─────────────────┐ │ 一只猫 │ │ ╱╲ ╱╲ │ │ 坐在窗台 │ → │ ╱ ╲ ╱ ╲ │ │ 上晒太阳 │ ││ ████ │ │ └─────────┘ └─────────────────┘
|
2.3 形态学操作
1 2 3 4 5 6 7 8 9 10 11 12 13
| kernel = np.ones((5, 5), np.uint8)
eroded = cv2.erode(binary, kernel, iterations=1)
dilated = cv2.dilate(binary, kernel, iterations=1)
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
|
2.4 图像变换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| resized = cv2.resize(img, (224, 224))
(h, w) = img.shape[:2] center = (w // 2, h // 2) matrix = cv2.getRotationMatrix2D(center, 45, 1.0) rotated = cv2.warpAffine(img, matrix, (w, h))
matrix = np.float32([[1, 0.2, 0], [0.2, 1, 0]]) affined = cv2.warpAffine(img, matrix, (w, h))
pts1 = np.float32([[50,50], [200,50], [50,200], [200,200]]) pts2 = np.float32([[0,0], [300,0], [0,300], [300,300]]) matrix = cv2.getPerspectiveTransform(pts1, pts2) warped = cv2.warpPerspective(img, matrix, (300, 300))
|
三、特征提取:从手工特征到深度学习
3.1 传统特征(深度学习之前)
1 2 3 4 5 6 7 8 9 10
| sift = cv2.SIFT_create() keypoints, descriptors = sift.detectAndCompute(gray, None)
orb = cv2.ORB_create() keypoints_orb, descriptors_orb = orb.detectAndCompute(gray, None)
img_kp = cv2.drawKeypoints(img, keypoints, None)
|
SIFT 能检测出对旋转、缩放、光照都不敏感的关键点——这也正是 CNN 卷积核在做的事,只不过 CNN 用学习的方式找出了更好的特征。
3.2 深度学习特征
CNN 的每一层都在提取不同层次的”特征”:
| 卷积层 |
学到的特征 |
可视化 |
| Layer 1 |
边缘、颜色、纹理 |
▓ ▒ ░ |
| Layer 2 |
角点、弧线、简单形状 |
⬡ ◇ ○ |
| Layer 3 |
眼睛、轮子、窗口(物体部件) |
👁 ⚙ 🪟 |
| Layer 4+ |
人脸、汽车、建筑(完整物体) |
🚗 🏠 👤 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import torch import torch.nn as nn from torchvision import models, transforms from PIL import Image
resnet = models.resnet50(pretrained=True) feature_extractor = nn.Sequential(*list(resnet.children())[:-1]) feature_extractor.eval()
transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ])
img = Image.open('example.jpg') input_tensor = transform(img).unsqueeze(0)
with torch.no_grad(): features = feature_extractor(input_tensor)
feature_vector = features.squeeze().numpy() print(f"特征向量维度: {feature_vector.shape}")
|
这个 2048 维的向量就是 ResNet 对这张图片的”理解”——两张内容相似的图片,特征向量的距离应该很近。
四、CV 任务全景
4.1 六大核心任务
1 2 3 4 5 6 7 8 9 10 11 12 13
| 计算机视觉 ├── 图像分类 ─── "这是什么?" │ └── ResNet、EfficientNet、ViT ├── 目标检测 ─── "东西在哪?" │ └── YOLO、Faster R-CNN、DETR ├── 语义分割 ─── "每个像素属于什么?" │ └── U-Net、DeepLab ├── 实例分割 ─── "每个物体的轮廓?" │ └── Mask R-CNN ├── 关键点检测 ─── "关节在哪?" │ └── OpenPose、HRNet └── 图像生成 ─── "画一张图" └── GAN、Stable Diffusion、DALL·E
|
4.2 常用数据集
| 数据集 |
任务 |
规模 |
指标 |
| ImageNet |
分类 |
1400万张,1000类 |
Top-1 / Top-5 |
| COCO |
检测+分割 |
33万张,80类 |
mAP |
| CIFAR-10/100 |
分类 |
6万张,10/100类 |
Accuracy |
| MNIST |
分类 |
7万张,10类 |
Accuracy |
| Cityscapes |
语义分割 |
5000张街景 |
mIoU |
4.3 CV 领域的”ImageNet 时刻”
1 2 3 4 5 6 7 8 9
| AlexNet (2012) → 超越传统方法,深度学习时代开启 VGG (2014) → 更深的网络,模块化设计 ResNet (2015) → 残差连接,152 层也训得动 YOLO (2016) → 实时目标检测 GAN (2014-2018) → 图像生成 ViT (2020) → Transformer 打败 CNN CLIP (2021) → 图文多模态 SAM (2023) → 通用分割模型 Stable Diffusion (2022-2026) → 文生图主流
|
五、数据增强
数据增强是 CV 项目中最有效的”免费午餐”——不需要新数据,通过变换现有数据来提升泛化能力。
1 2 3 4 5 6 7 8 9 10 11 12
| from torchvision import transforms
train_transform = transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ColorJitter(0.2, 0.2, 0.2), transforms.RandomAffine(degrees=10, translate=(0.1, 0.1)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ])
|
常用增强策略:
- 几何变换:翻转、旋转、裁剪、缩放
- 颜色变换:亮度、对比度、饱和度
- 噪声:高斯噪声、椒盐噪声
- 高级:Cutout(随机遮挡)、MixUp(混合两张图)、CutMix
六、总结
| 知识点 |
掌握 |
| 图像在计算机中的表示(RGB/灰度/H×W×C) |
✅ |
| OpenCV 基础操作(滤波/边缘/形态学) |
✅ |
| 传统特征 vs 深度学习特征 |
✅ |
| 用预训练 CNN 提取特征向量 |
✅ |
| CV 六大任务与经典模型 |
✅ |
| 数据增强方法与策略 |
✅ |
下一步推荐: