開運算:先腐蝕后膨脹,作用是使狹窄的白色連接斷開,消除白點。
閉運算:先膨脹后腐蝕,作用是使狹窄的白色連接彌合,消除黑點。
開運算和閉運算是對偶的,然而與腐蝕膨脹不同的是,對於某圖像應用多次開或閉運算,和只進行一次運算的效果相同。
一、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.