FPGA实现图像中心差分变换

  差分图像就是目标场景在连续时间点图像相减所构成的图像,广义的差分图像定义为目标场景在时间点tk和tk+L所成图像的差别。差分图像是由目标场景在相邻时间点的图像相减得到的,从而能够得到目标场景随时间的变换。

  差分图像在许多领域得到了广泛的应用,比如:视频压缩,生物医学诊断,天文学,遥感,人脸识别等。

 

——FPGA开源工作室

一、MATLAB实现

1、主文件 img_diff.m

%--------------------------------------------------------------------------
%                       中心差分变换
%--------------------------------------------------------------------------
clc;
clear all;
RGB  = imread('flower.bmp');        %读取图像
Gray = rgb2gray(RGB);
Diff = mipcentraldiff(Gray,'dx');

subplot(2,2,1);imshow(RGB); title('原图');
subplot(2,2,3);imshow(Gray);title('灰度图');
subplot(2,2,4);imshow(Diff);title('中心差分变换');

2、子文件 mip1centraldiff.m

%--------------------------------------------------------------------------
%     img:          input image
%     direction:    'dx' or 'dy'
%     dimg:         resultant image
%--------------------------------------------------------------------------
function dimg = mipcentraldiff(img,direction)
img = padarray(img,[1,1],'symmetric','both');
[row,col] = size(img);
dimg = zeros(row,col);
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);

3、运行结果

  在主文件 img_diff.m 中点击运行,得到如下结果:

 

二、FPGA实现

  FPGA中同样采用灰度分量 Y 来实现中心差分变换,对于如何实现灰度分量Y,可以查看前面的博客介绍。我们可以将公式变一下形,如下所示:

  Ix = [I(x+2h) - I(x)] / 2h

  取 h 的值为1,则公式变成 Ix = [I(x+2) - I(x)] / 2 

1、打拍

  和前面 FPGA 实现浮雕效果一样,通过打拍实现像素值的延迟,代码如下所示:

//==========================================================================
//==                        打拍
//==========================================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        {Y_de_r2,   Y_de_r1   } <= {1'b0,1'b0};
        {Y_hsync_r2,Y_hsync_r1} <= {1'b0,1'b0};
        {Y_vsync_r2,Y_vsync_r1} <= {1'b0,1'b0};
        {Y_data_r2, Y_data_r1 } <= {8'b0,8'b0};
    end
    else begin
        {Y_de_r2,   Y_de_r1   } <= {Y_de_r1,   Y_de   };
        {Y_hsync_r2,Y_hsync_r1} <= {Y_hsync_r1,Y_hsync};
        {Y_vsync_r2,Y_vsync_r1} <= {Y_vsync_r1,Y_vsync};
        {Y_data_r2, Y_data_r1 } <= {Y_data_r1, Y_data };
    end
end

2、中心差分变换

  对着公式写代码即可,除以 2 的操作我们采用右移 1 位来实现。

//==========================================================================
//==                        中心差分变换
//==========================================================================
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        diff_data <= 8'd0;
    end
    else begin
        diff_data <= (Y_data_r2 - Y_data) >> 1;
    end
end

3、信号同步

  这个说了很多遍了,直接将打拍后的信号赋值出去即可。

//==========================================================================
//==                        信号同步
//==========================================================================
assign diff_de = Y_de_r2;
assign diff_hsync = Y_hsync_r2;
assign diff_vsync = Y_vsync_r2;

 

三、上板验证

  最后在 FPGA 开发板的 TFT 屏中,我们得到如下的实验结果:

  从结果可以看出,大体和 MATLAB 中的效果一样,但是有细微的差别,这是因为 (Y_data_r2 - Y_data) 的计算结果可能为负数或奇数,如果要达到完美,公式还得继续改造,这个图像变换比较简单,不想废心思了,有兴趣的同学可以自己尝试看看。

  此外也可以将中心差分变换的算法移植到 RGB 三通道,实现彩色输出的中心差分变换。

 

参考资料:[1] OpenS Lee:FPGA开源工作室(公众号)

 

posted @ 2020-03-12 12:47  咸鱼IC  阅读(1327)  评论(0编辑  收藏  举报