3、图像数据采集:相机标定、多视角拍摄、光照与角度控制、数据存储格式

图像数据采集,说白了就是给AI喂“好照片”。

我见过太多项目,模型结构选得挺好,训练参数也调得不错,结果数据采集阶段就翻车了。拍出来的照片要么畸变严重,要么光照不均,要么角度单一。模型再怎么折腾,上限也就那样了。

这一节,咱们就聊聊怎么把图像数据采集这件事做扎实。

3.1 相机标定:让相机“说实话”

相机标定,是图像采集的第一步,也是最容易被忽略的一步。

你想想看,相机镜头本身就有畸变。广角镜头拍出来的照片,边缘都是弯的。如果不做标定,你采集的图像坐标就是错的。后续的目标检测、语义分割,全都会跟着偏。

核心要点:相机标定的本质,是求解相机的内参矩阵和畸变系数。

我个人习惯用棋盘格标定板。为什么?因为棋盘格的角点检测算法非常成熟,OpenCV里直接就有现成的函数。

具体步骤是这样的:

  1. 打印一张棋盘格标定板,贴在平整的硬板上。
  2. 从不同角度拍摄15-20张照片。注意,要覆盖画面的各个区域。
  3. 用OpenCV的 cv2.findChessboardCorners() 检测角点。
  4. 调用 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)
我的经验:标定板一定要平整。我曾经用一张皱巴巴的A4纸做标定,结果算出来的畸变系数全是错的。后来换了亚克力板,一次就过了。

3.2 多视角拍摄:别让AI“偏科”

AI模型如果只见过正面视角的猫,那它看到猫屁股时,大概率会懵掉。

多视角拍摄,就是为了解决这个问题。你需要让采集的图像覆盖尽可能多的观察角度。

我建议至少覆盖以下视角:

  • 俯视:适合桌面场景、文档扫描。
  • 平视:适合行人检测、人脸识别。
  • 仰视:适合无人机视角、建筑拍摄。
  • 侧视:适合车辆检测、动作识别。

在实际项目中,我通常会搭建一个多相机阵列。比如做自动驾驶数据集时,我们在车顶装了6个相机,覆盖360度环视。这样采集到的数据,模型才能学会应对各种路况。

注意:多视角拍摄时,要保证相机之间的相对位置固定。否则后续的坐标对齐会非常麻烦。

3.3 光照与角度控制:别让AI“看走眼”

光照是图像采集里最“玄学”的部分。同一个物体,在强光下和暗光下,拍出来的图像差异巨大。

我踩过这个坑。有一次做工业质检项目,白天采集的数据模型表现很好,一到夜班就崩了。后来发现,白天和晚上的光照条件完全不同。

怎么控制?我的做法是:

  1. 使用恒定光源:比如环形灯、条形灯,保证光照强度稳定。
  2. 记录光照参数:在采集时,同步记录色温、照度值。
  3. 模拟极端光照:故意在强逆光、弱光环境下采集一部分数据。

角度控制方面,我推荐使用电动旋转台。把物体放在转台上,相机固定,然后按固定角度步进拍摄。比如每10度拍一张,这样就能得到均匀的角度覆盖。

避坑指南:我曾经用人工手动旋转物体来采集多角度数据,结果角度间隔不均匀,模型训练时对某些角度特别敏感。后来换了电动转台,问题就解决了。

3.4 数据存储格式:选对格式,事半功倍

图像数据存成什么格式,直接影响存储成本和读取速度。

常见的格式有:

格式 特点 适用场景
JPEG 有损压缩,文件小 大规模数据集,对精度要求不高
PNG 无损压缩,支持透明通道 需要精确边缘、文字识别
BMP 无压缩,文件大 工业检测,需要原始像素值
TIFF 支持多页、元数据 遥感图像、医学影像

我个人习惯用PNG格式。虽然文件比JPEG大一些,但无损压缩保证了像素精度。尤其是在做语义分割标注时,标注图必须是PNG,否则压缩会引入锯齿。

另外,我建议把图像数据统一命名为 class_id_frame_number.jpg 这样的格式。比如 cat_0001.jpg。这样在后期处理时,按文件名就能快速筛选。

小技巧:如果数据集特别大,可以考虑用LMDB或HDF5这种二进制格式存储。读取速度比单张图片快很多。

知识体系总览

下面这张图,把图像数据采集的核心流程串起来了。你可以对照着看,每一步都别漏掉。

图像数据采集核心流程 相机标定 多视角拍摄 光照与角度控制 数据存储格式 内参矩阵 畸变系数 俯视/平视/仰视/侧视 多相机阵列 恒定光源 电动旋转台 JPEG/PNG/BMP/TIFF LMDB/HDF5

嗯,图像数据采集这块,核心就是这四步。每一步都做到位,后面标注和训练才能顺风顺水。


专注资料整理