仿射变换及坐标变换公式
几何变换改进图像中像素间的空间关系。这些变换通常称为橡皮模变换,因为它们可看成是在一块橡皮模上印刷一幅图像,然后根据预定的一组规则拉伸该薄膜。在数字图像处理中,几何变换由两个基本操作组成:
(1)坐标的空间变换
(2)灰度内插,即对变换后的像素赋灰度值
坐标变换公式
(x,y) = T{(v, w)}
其中,(v, w)是原图像中像素的坐标,(x, y)是变换后图像中像素的坐标。最常用的空间坐标变换之一是仿射变换
基于上式的仿射变换公式
实际上,我们可以用两种方法来使用上式。第一种方法称为向前映射,它由扫描输入图像的像素,并在每个位置(v, w)用上式直接计算输出图像中相应像素的空间位置(x, y)组成。向前映射算法的一个问题是输入图像中的两个或更多个像素可被变换到输出图像的同一位置,这就产生了如何把多个输出值合并到一个输出像素的问题。第二种方法,反向映射,扫描输出像素的位置,并在每一个位置(x, y)使用(v, w) = T-1(x, y)计算输入图像中的相应位置。然后通过内插决定输出像素的灰度值。本篇文章使用反向映射。
<以上基础知识来源于 《数字图像处理》冈萨雷斯 P50-P51 读者可自行查阅>
在上一篇文章中,主要是图片的放大与缩小,在灰度内插的过程中也涉及到目标图像到原图像的坐标变换,代码如下
1 void bilinera_interpolation(short** in_array, short height, short width, 2 short** out_array, short out_height, short out_width) 3 { 4 double h_times = (double)out_height / (double)height, 5 w_times = (double)out_width / (double)width; 6 short x1, y1, x2, y2, f11, f12, f21, f22; 7 double x, y; 8 9 for (int i = 0; i < out_height; i++){ 10 for (int j = 0; j < out_width; j++){ 11 x = j / w_times; 12 y = i / h_times; 13 x1 = (short)(x - 1); 14 x2 = (short)(x + 1); 15 y1 = (short)(y + 1); 16 y2 = (short)(y - 1); 17 f11 = is_in_array(x1, y1, height, width) ? in_array[y1][x1] : 0; 18 f12 = is_in_array(x1, y2, height, width) ? in_array[y2][x1] : 0; 19 f21 = is_in_array(x2, y1, height, width) ? in_array[y1][x2] : 0; 20 f22 = is_in_array(x2, y2, height, width) ? in_array[y2][x2] : 0; 21 out_array[i][j] = (short)(((f11 * (x2 - x) * (y2 - y)) + 22 (f21 * (x - x1) * (y2 - y)) + 23 (f12 * (x2 - x) * (y - y1)) + 24 (f22 * (x - x1) * (y - y1))) / ((x2 - x1) * (y2 - y1))); 25 } 26 } 27 }