3. 图像几何变换
几何变换改变的是像素在图像平面上的空间位置,而不是像素本身的颜色值。MATLAB 图像处理工具箱把最常用的四类操作封装为 imresize、imrotate、imcrop、imtranslate 四个函数。理解它们的共同点与差异,是后续做配准、数据增强、ROI 提取和透视校正的基础。
先明确本节的坐标约定:MATLAB 图像采用矩阵索引,I(r,c) 中 r 为行号(向下增大),c 为列号(向右增大)。imtranslate 的位移向量写作 [dx dy],其中 dx 沿列方向(水平向右为正),dy 沿行方向(垂直向下为正)。imrotate 默认以图像中心为旋转中心,正角度表示逆时针旋转。全文与图示均遵循这一约定。
四个函数的输入输出与关键参数
imresize 接收图像和目标尺寸或缩放因子,输出重采样后的图像。常用写法是 J = imresize(I, 0.5)(缩小一半)或 J = imresize(I, [256 256])(指定输出行列数)。它默认使用双三次插值,可通过 'Method' 指定 'nearest'、'bilinear'、'bicubic' 等。
imrotate 的调用形式为 J = imrotate(I, angle, method, 'crop')。默认 'loose' 会扩大画布以容纳旋转后的完整图像,'crop' 则保持原尺寸并裁掉超出部分。旋转后出现的空白区域默认填充 0(黑色),可用 'FillValues' 指定填充值。
imcrop 用于裁剪矩形区域,交互式写法是 J = imcrop(I),程序化写法是 J = imcrop(I, rect),其中 rect = [xmin ymin width height]。注意这里的 xmin 是列方向起点,ymin 是行方向起点,与矩阵索引顺序相反,这是初学者最容易出错的地方。
imtranslate 的调用形式为 J = imtranslate(I, [dx dy]),可配合 'OutputView' 选择 'same'(保持原尺寸)或 'full'(扩大画布显示全部内容)。平移不改变图像内容,只改变其在画布中的位置。
插值方法:几何变换的质量核心
几何变换的本质是“反向映射 + 重采样”。以缩放为例,输出图像每个像素 (r', c') 先通过逆变换求出它在原图中的对应位置 (r, c),这个位置通常落在非整数坐标上,于是需要根据周围像素估计该点的灰度值,这就是插值。
四种常用插值方法的差异可以这样理解:'nearest' 直接取最近整数像素,速度最快,但放大后边缘呈明显块状锯齿;'bilinear' 用 2×2 邻域做线性加权,结果平滑但高频细节会被削弱;'bicubic' 用 4×4 邻域做三次卷积,在平滑与锐度之间取得较好平衡,是 imresize 的默认方法;'lanczos2' 或 'lanczos3' 使用更宽的核,边缘更锐利,但计算量更大,且可能产生轻微振铃。
选择原则并不复杂:缩小图像时,'bicubic' 或 'lanczos' 能减少混叠;放大图像时,若追求速度可用 'bilinear',若追求质量用 'bicubic';只有在做标签图、索引图或掩膜时,才必须使用 'nearest',因为这类图像的像素值代表类别编号,插值产生的中间值没有物理意义。
'nearest',否则会引入不存在的类别值。实操示例:一次完整的几何变换流程
下面以一张 480×640 的灰度图像 I 为例,演示四个函数的组合使用。示例参数属于教学假设,实际运行时请替换为自己的图像。
I = imread('camera.jpg');
if size(I,3) == 3
I = rgb2gray(I);
end
% 1. 缩放:缩小到 60%,使用双三次插值
I_small = imresize(I, 0.6, 'bicubic');
% 2. 旋转:逆时针 15°,保持原尺寸,空白填 128
I_rot = imrotate(I, 15, 'bilinear', 'crop', 'FillValues', 128);
% 3. 裁剪:从 (100, 80) 开始取 200×160 区域
rect = [100 80 200 160];
I_crop = imcrop(I, rect);
% 4. 平移:向右 30 像素,向下 20 像素
I_trans = imtranslate(I, [30 20], 'OutputView', 'same');
% 显示对比
figure;
subplot(2,3,1); imshow(I); title('原图');
subplot(2,3,2); imshow(I_small); title('缩放 0.6');
subplot(2,3,3); imshow(I_rot); title('旋转 15°');
subplot(2,3,4); imshow(I_crop); title('裁剪');
subplot(2,3,5); imshow(I_trans); title('平移 [30 20]');
运行后应重点观察三处:旋转图的四角是否出现填充色(本例为 128 灰),裁剪图的尺寸是否为 160×200(注意 size 返回的是行×列,即高×宽),平移图右侧和下侧是否出现黑色或填充区域。这些现象直接反映参数是否按预期生效。
参数与结果的对应关系
| 函数 | 关键参数 | 典型取值 | 结果观察点 |
|---|---|---|---|
| imresize | scale / outputSize | 0.5、[256 256] | 输出尺寸、边缘锯齿或模糊 |
| imrotate | angle、bbox、FillValues | 15、'crop'、128 | 四角填充、内容是否被裁掉 |
| imcrop | rect = [x y w h] | [100 80 200 160] | 输出宽高、ROI 位置是否正确 |
| imtranslate | [dx dy]、OutputView | [30 20]、'same' | 位移方向、边界填充区域 |
常见问题与排查
第一类问题是方向反了。若发现平移方向与预期相反,先检查是否把 [dx dy] 写成了 [dy dx];若旋转方向反了,确认正角度是否为逆时针。第二类问题是裁剪区域偏移,多数情况是把 rect 的 [x y] 误当成矩阵的 [row col],记住 x 对应列、y 对应行。第三类问题是旋转后图像变黑或出现异常色块,通常是填充值设置不当,或对彩色图逐通道处理时未统一填充值。第四类问题是缩放后图像模糊,若原图本身分辨率低,任何插值都无法恢复丢失的细节,此时应考虑先做锐化或改用更高分辨率源图。
imresize、imrotate、imtranslate 会自动对三个通道分别处理,但填充值需以三元向量给出,例如 'FillValues', [128 128 128],否则可能报错或产生颜色偏差。掌握这四个函数后,可以进一步组合出更复杂的操作:先旋转再裁剪得到校正后的 ROI,先缩放再平移实现多尺度模板匹配,或对同一张图施加随机旋转和平移生成数据增强样本。几何变换的参数选择与插值方法,最终都要回到具体任务对精度、速度和语义一致性的要求上来判断。