简单处理——FPGA实现图像中心差分变换
一、图像中心差分变换算法简介
差分图像就是目标场景在连续时间内图像相减所构成的图像,对图像进行中心差分变换的主要目的是计算图像中心每个像素点的梯度,而 每个像素点的梯度在图像处理中就可以被用于描述图像中灰度变化的快慢和方向。
广义的差分图像定义为目标场景点在相邻时间点的图像相减得到的。公式为:
Ix = (I(x+1)-I(x-1))/2
实际在进行中心差分计算的过程中还需要主义的是所计算梯度的方向,是分dx和dy的,也就是分为水平方向的中心差分计算和垂直方向的中心差分计算的;水平方向的中心差分计算简单通过打拍即可进行相加减,垂直方向的中心差分计算可能要涉及到多FIFO的流水线操作,本节中暂不进行相关介绍,在sobel算子的相应章节会进行相关介绍。
二、MATLAB实现
function dimg =centraldiff(img,direction)
%表示对输入的img进行边界填充,symmetric表示是对称填充方式,both表示上下左右都进行填充
img = padarray(img,[1,1],'symmetric','both');
%获取边界填充之后图像的行列信息,理论上都是原来的基础上+2
[row,col] = size(img);
dimg = zeros(row,col);
%根据所选择的方向分别进行差分运算,这里由于是一个后向减前向除以2,边界填充再差分之后刚刚好与原来一致
switch(direction)
case'dx'
dimg(:,2:col-1)= (img(:,3:col)-img(:,1:col-2))/2;
case'dy'
dimg(2:row-1,:)= (img(3:row,:)-img(1:row-2,:))/2;
otherwise
disp('Direction is unknown');
end
%完事了之后要进行裁剪,剪掉之前填充的像素
dimg = dimg(2:end-1,2:end-1);
和我们之前进行的差分化处理来对比的话,中心差分变化更侧重于像素本身变化的大小,而不是视觉上的视觉突出,所以理论上更适用于生物医学v诊断和遥感影像。
三、FPGA实现与上板实现
//对差分数据的差右移一位以完成除以2的操作
assign cdc_data = (pre_data - pre_data_d2) >> 1;
//对数据进行打两拍,同时对时序打拍让时序对齐
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
// reset
pre_hsync_d <= 0;
pre_vsync_d <= 0;
pre_de_d <= 0;
{pre_data_d2, pre_data_d1} <= 0;
end
else begin
{pre_hsync_d[1], pre_hsync_d[0]} <= {pre_hsync_d[0], pre_hsync};
{pre_vsync_d[1], pre_vsync_d[0]} <= {pre_vsync_d[0], pre_vsync};
{pre_de_d[1], pre_de_d[0]} <= {pre_de_d[0], pre_de};
{pre_data_d2, pre_data_d1} <= {pre_data_d1, pre_data};
end
end
可以看到总体的实现效果是不错的,细微处可能有所区别,可能的原因有两处:一是差分图像计算的结果可能为负数,在Verilog中无符号数相加减得到的值如果为负数,可能会隐去超出位宽的符号位,以补码形式来表示,得到负数时候可以对其求绝对值或者赋值0;二是在verilog实现过程中最后还要进行一个位宽匹配,将8bit数据转换为16bit,具体的成像的一个视觉效果会有所不同。