3、图像数据采集:相机标定、多视角拍摄、光照与角度控制、数据存储格式
图像数据采集,说白了就是给AI喂“好照片”。
我见过太多项目,模型结构选得挺好,训练参数也调得不错,结果数据采集阶段就翻车了。拍出来的照片要么畸变严重,要么光照不均,要么角度单一。模型再怎么折腾,上限也就那样了。
这一节,咱们就聊聊怎么把图像数据采集这件事做扎实。
3.1 相机标定:让相机“说实话”
相机标定,是图像采集的第一步,也是最容易被忽略的一步。
你想想看,相机镜头本身就有畸变。广角镜头拍出来的照片,边缘都是弯的。如果不做标定,你采集的图像坐标就是错的。后续的目标检测、语义分割,全都会跟着偏。
我个人习惯用棋盘格标定板。为什么?因为棋盘格的角点检测算法非常成熟,OpenCV里直接就有现成的函数。
具体步骤是这样的:
- 打印一张棋盘格标定板,贴在平整的硬板上。
- 从不同角度拍摄15-20张照片。注意,要覆盖画面的各个区域。
- 用OpenCV的
cv2.findChessboardCorners()检测角点。 - 调用
cv2.calibrateCamera()计算内参和畸变系数。
import cv2
import numpy as np
# 棋盘格尺寸
chessboard_size = (9, 6)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2)
objpoints = [] # 世界坐标系中的点
imgpoints = [] # 图像坐标系中的点
images = glob.glob('calib_images/*.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)
if ret:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners2)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
3.2 多视角拍摄:别让AI“偏科”
AI模型如果只见过正面视角的猫,那它看到猫屁股时,大概率会懵掉。
多视角拍摄,就是为了解决这个问题。你需要让采集的图像覆盖尽可能多的观察角度。
我建议至少覆盖以下视角:
- 俯视:适合桌面场景、文档扫描。
- 平视:适合行人检测、人脸识别。
- 仰视:适合无人机视角、建筑拍摄。
- 侧视:适合车辆检测、动作识别。
在实际项目中,我通常会搭建一个多相机阵列。比如做自动驾驶数据集时,我们在车顶装了6个相机,覆盖360度环视。这样采集到的数据,模型才能学会应对各种路况。
3.3 光照与角度控制:别让AI“看走眼”
光照是图像采集里最“玄学”的部分。同一个物体,在强光下和暗光下,拍出来的图像差异巨大。
我踩过这个坑。有一次做工业质检项目,白天采集的数据模型表现很好,一到夜班就崩了。后来发现,白天和晚上的光照条件完全不同。
怎么控制?我的做法是:
- 使用恒定光源:比如环形灯、条形灯,保证光照强度稳定。
- 记录光照参数:在采集时,同步记录色温、照度值。
- 模拟极端光照:故意在强逆光、弱光环境下采集一部分数据。
角度控制方面,我推荐使用电动旋转台。把物体放在转台上,相机固定,然后按固定角度步进拍摄。比如每10度拍一张,这样就能得到均匀的角度覆盖。
3.4 数据存储格式:选对格式,事半功倍
图像数据存成什么格式,直接影响存储成本和读取速度。
常见的格式有:
| 格式 | 特点 | 适用场景 |
|---|---|---|
| JPEG | 有损压缩,文件小 | 大规模数据集,对精度要求不高 |
| PNG | 无损压缩,支持透明通道 | 需要精确边缘、文字识别 |
| BMP | 无压缩,文件大 | 工业检测,需要原始像素值 |
| TIFF | 支持多页、元数据 | 遥感图像、医学影像 |
我个人习惯用PNG格式。虽然文件比JPEG大一些,但无损压缩保证了像素精度。尤其是在做语义分割标注时,标注图必须是PNG,否则压缩会引入锯齿。
另外,我建议把图像数据统一命名为 class_id_frame_number.jpg 这样的格式。比如 cat_0001.jpg。这样在后期处理时,按文件名就能快速筛选。
知识体系总览
下面这张图,把图像数据采集的核心流程串起来了。你可以对照着看,每一步都别漏掉。
嗯,图像数据采集这块,核心就是这四步。每一步都做到位,后面标注和训练才能顺风顺水。