图像平移就是将图像中所有的点按照指定的平移量水平或者垂直移动。
设(x0,y0)为图像上的一点,图像水平平移量为Tx,垂直平移量为Ty,如图所示:
则平移之后的点坐标(x1,y1)变为:
用矩阵表示为:
对变换矩阵求逆,可以得到逆变换:
即:
这样,平移后的目标图像中的每一点都可以在原图像中找到对应的点。例如,将新图中的(i,j)像素,代入上面的方程组,可以求出对应原图中的像素(i-Tx, j-Ty). 而此时如果Tx大于 i 或大于 j,则点 (i-Tx, j-Ty)超出了原图的范围,可以直接将它的像素值统一设置为0或者255。
对于原图中被移出图像显示区域的点通常也有两种处理方法:直接丢弃或者通过适当增加目标图像的尺寸(将新生成的图像宽度增加Tx,高度增加Ty)的方法使新图像中能够包含这些点。在稍后给出的程序实现中,我们采用了第-一种处理方法。
一、MATLAB实现
MATLAB中没有直接用于图像平移的函数,这里给出一个基于灰度形态学的图像平移实现。
%-------------------------------------------------------------------------- % 图像平移 %-------------------------------------------------------------------------- clc; clear all; RGB = imread('monkey.jpg'); %读取图像 se = translate(strel(1),[-30,20]); %strel创建形态学结构元素,然后偏移 trans = imdilate(RGB,se); subplot(1,2,1),imshow(RGB); title('原图'); subplot(1,2,2),imshow(trans);title('平移');
点击运行,得到如下结果:
二、FPGA实现
平移的实现和前面相比,多了两个偏移参数,由于偏移量有正有负,因此定义成有符号数,如下所示:
parameter COL = 10'd140 ; //图片长度 parameter ROW = 10'd140 ; //图片高度 parameter IMG_x = 10'd170 ; //图片起始横坐标 parameter IMG_y = 10'd66 ; //图片起始纵坐标 //--------------------------------------------------- parameter signed x_add = 20 ; //x轴偏移 parameter signed y_add = -30 ; //y轴偏移
关于平移的算法总的来说比较简单,核心思想即构建新的坐标数值对应关系,坐标改为原先坐标基础加上偏移量。此外需要注意的是,新坐标是旧坐标加上偏移量,偏移量可能是负数,因此新坐标的结果也可能是负数,也要和上面的 x_add 和 y_add 一样定义成有符号数。同时需要进行判定,如果新的坐标值超过原有的图像范围,则选择丢弃。
wire signed [9:0] new_cnt_col ; //新横坐标 wire signed [9:0] new_cnt_row ; //新纵坐标 //========================================================================== //== 平移 //========================================================================== assign new_cnt_col = cnt_col + x_add; assign new_cnt_row = cnt_row + y_add; always @(*) begin if(new_cnt_col > COL-1 || new_cnt_row > ROW-1 || new_cnt_col < 0 || new_cnt_row < 0) begin trans_cnt_col <= 'd0; trans_cnt_row <= 'd0; end else begin trans_cnt_col <= new_cnt_col; trans_cnt_row <= new_cnt_row; end end
三、上板验证
上板结果和 MATLAB 结果一致,此次平移实验设计成功。
参考资料:
[1] OpenS Lee:FPGA开源工作室(公众号)
[2] 张铮, 王艳平, 薛桂香. 数字图像处理与机器视觉[M]. 人民邮电出版社, 2010.