FPGA实现图像的形态学滤波:开运算和闭运算

  开运算:先腐蚀后膨胀,作用是使狭窄的白色连接断开,消除白点。

  闭运算:先膨胀后腐蚀,作用是使狭窄的白色连接弥合,消除黑点。

  开运算和闭运算是对偶的,然而与腐蚀膨胀不同的是,对于某图像应用多次开或闭运算,和只进行一次运算的效果相同。

一、MATLAB实现

clc;
clear all;
close all;

RGB = imread('lou.jpg');          %读取图片
gray = double(rgb2gray(RGB));     %灰度图
[ROW,COL, DIM] = size(gray);      %得到图像行列数
%------------------------------< Sobel >-----------------------------------
value = 70; %阈值设置
Sobel_img = zeros(ROW,COL);
for r = 2:ROW-1
    for c = 2:COL-1
        Gx = gray(r-1,c+1) + 2*gray(r,c+1) + gray(r+1,c+1) - gray(r-1,c-1) - 2*gray(r,c-1) - gray(r+1,c-1);
        Gy = gray(r-1,c-1) + 2*gray(r-1,c) + gray(r-1,c+1) - gray(r+1,c-1) - 2*gray(r+1,c) - gray(r+1,c+1);
        G = abs(Gx) + abs(Gy);
        %G = sqrt(Gx^2 + Gy^2);
        if(G >= value)
            Sobel_img(r,c)=255;
        else
            Sobel_img(r,c)=0;
        end
    end
end%------------------------------< open >-----------------------------------
Erode_img = zeros(ROW,COL);
for r = 2:ROW-1
    for c = 2:COL-1
        and1 = bitand(Sobel_img(r-1, c-1), bitand(Sobel_img(r-1, c), Sobel_img(r-1, c+1)));
        and2 = bitand(Sobel_img(  r, c-1), bitand(Sobel_img(  r, c), Sobel_img(  r, c+1)));
        and3 = bitand(Sobel_img(r+1, c-1), bitand(Sobel_img(r+1, c), Sobel_img(r+1, c+1)));
        Erode_img(r, c) = bitand(and1, bitand(and2, and3));
    end
end
Dilate_img = zeros(ROW,COL);
for r = 2:ROW-1
    for c = 2:COL-1
        or1 = bitor(Erode_img(r-1, c-1), bitor(Erode_img(r-1, c), Erode_img(r-1, c+1)));
        or2 = bitor(Erode_img(  r, c-1), bitor(Erode_img(  r, c), Erode_img(  r, c+1)));
        or3 = bitor(Erode_img(r+1, c-1), bitor(Erode_img(r+1, c), Erode_img(r+1, c+1)));
        Dilate_img(r, c) = bitor(or1, bitor(or2, or3));
    end
end
open_img = Dilate_img;
%------------------------------< close >-----------------------------------
img_Dilate = zeros(ROW,COL);
for r = 2:ROW-1
    for c = 2:COL-1
        or1 = bitor(Sobel_img(r-1, c-1), bitor(Sobel_img(r-1, c), Sobel_img(r-1, c+1)));
        or2 = bitor(Sobel_img(  r, c-1), bitor(Sobel_img(  r, c), Sobel_img(  r, c+1)));
        or3 = bitor(Sobel_img(r+1, c-1), bitor(Sobel_img(r+1, c), Sobel_img(r+1, c+1)));
        img_Dilate(r, c) = bitor(or1, bitor(or2, or3));
    end
end
img_Erode = zeros(ROW,COL);
for r = 2:ROW-1
    for c = 2:COL-1
        and1 = bitand(img_Dilate(r-1, c-1), bitand(img_Dilate(r-1, c), img_Dilate(r-1, c+1)));
        and2 = bitand(img_Dilate(  r, c-1), bitand(img_Dilate(  r, c), img_Dilate(  r, c+1)));
        and3 = bitand(img_Dilate(r+1, c-1), bitand(img_Dilate(r+1, c), img_Dilate(r+1, c+1)));
        img_Erode(r, c) = bitand(and1, bitand(and2, and3));
    end
end
close_img = img_Erode;
%------------------------------< show >------------------------------------
subplot(2,2,1); imshow(RGB);       title('原图');
subplot(2,2,2); imshow(Sobel_img); title('Sobel算子');
subplot(2,2,3); imshow(open_img);  title('开运算');
subplot(2,2,4); imshow(close_img); title('闭运算');

  较之前的 Sobel 算子相比,阈值的二值进行了反转,最终效果由白底黑景变成黑底白景,这样才更方便印证形态学滤波的理论。点击运行,得到如下结果:

  从结果可以看到,开运算使得图像很多地方出现了断点,图像内部小白点消除了;闭运算则加强了线条连接,消除了很多黑点。

 二、FPGA实现

  代码就是腐蚀膨胀顺序不同,将开运算闭运算放到之前 Sobel 算子代码之后看看效果吧。

  Sobel算子图:

  开运算后:

  闭运算后:

  和我们的理论一致,实验成功。

参考资料:

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

[2] CrazyBingo:基于VIP_Board Mini的FPGA视频图像算法(HDL-VIP)开发教程-V1.6 

[3] NingHechuan:FPGA图像处理教程

[4] 牟新刚、周晓、郑晓亮.基于FPGA的数字图像处理原理及应用[M]. 电子工业出版社,2017.

[5] 张铮, 王艳平, 薛桂香. 数字图像处理与机器视觉[M]. 人民邮电出版社, 2010.

猜你喜欢

转载自www.cnblogs.com/xianyufpga/p/12551565.html