1、理論概念算法
區域生長是按照事先定義的生長準則將一個像素或者子區域逐步聚合成一個完整獨立的連通區域過程。對於圖像感興趣目標區域R,z爲區域R上事先發現的種子點,按照規定的生長準則逐步將與種子點z必定鄰域內符合類似性判據的像素合併成一個種子羣以備下一階段的生長,這樣不斷的進行循環生長直到知足生長中止條件爲止,從而完成了對感興趣區域由一個種子點生長爲一個獨立連通區域的過程。其中類似性判據能夠是像素灰度值、顏色、紋理特徵等圖像信息。數組
所以區域生長算法通常分爲三個步驟實現:函數
(1) 肯定生長種子點測試
(2) 規定生長準則ui
(3) 肯定生長中止條件spa
實際工程應用中區域生長算法常被用於對二值化圖像指定連通區域的分割。圖1以圖文方式對區域生長算法的三步驟進行解釋:blog
① 原始二值化圖像(a)中的紅色標註的像素爲指定生長點;遞歸
② 圖像(b)和(c)是採用不一樣生長準則進行區域生長的結果,其中圖(b)是在4鄰域下,待測像素與生長點像素灰度值相等的像素集合。正如圖中所示第1次生長時,與生長點像素灰度相等的像素有上、下、左、右四個像素,接着第二次生長時,就由前一次已經生長的像素按照一樣的準則進行下去,直到遇到圖像邊界或背景區域時生長中止。圖(c)是在8鄰域下,待測像素與生長點像素灰度值相等的像素集合。內存
2、MATLAB示例代碼實現get
2.1 主函數文件
%主文件 clc; clear all; close all; %申明全局變量 R:區域生長的結果圖像;BW:二值化圖像;counter:感興趣連通區域的像素個數 %row:圖像的行數;col:圖像的列數 global R BW counter row col I = imread('E:\MATLAB仿真\fsr.bmp'); I = I(:,:,1); [row,col] = size(I); figure,imshow(I); level = graythresh(I); BW = im2bw(I,level); figure,imshow(BW); [y0,x0] = getpts; x0 = uint32(x0); y0 = uint32(y0); counter = 0; R = zeros(row,col); R = uint8(R); fsrRegiongrow(x0,y0,4);% fsrRegiongrow1(x0,y0,4); figure,imshow(R);
2.2 函數模塊1
function fsrRegiongrow(x0,y0,mode) %功能: 經過函數遞歸方法對二值化圖像指定連通區域實現區域生長 %輸入參數: x0,y0表示生長點像素座標,mode表示以多大鄰域進行區域生長,常取mode = 4;mode = 8; %輸出參數: void %做者&時間: 奔跑在湘邊———2016年5月6日 global R BW counter row col if 8 == mode for i = -1 : 1 for j = -1 : 1 x1 = x0 + i; y1 = y0 + j; %生長準則:判斷生長點8鄰域內像素的各自灰度值是否與生長點所在像素灰度值相等 if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1) R(x1,y1) = 255; counter = counter + 1; fsrRegiongrow(x1,y1,mode); end end end elseif 4 == mode for i = -1 : 1 x1 = x0 + i; y1 = y0; if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1) R(x1,y1) = 255; counter = counter + 1; fsrRegiongrow(x1,y1,mode); end end x1 = x0; y1 = y0 - 1; if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1) R(x1,y1) = 255; counter = counter + 1; fsrRegiongrow(x1,y1,mode); end x1 = x0; y1 = y0 + 1; if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1) R(x1,y1) = 255; counter = counter + 1; fsrRegiongrow(x1,y1,mode); end end end
2.3 函數模塊2
function fsrRegiongrow1(x0,y0,mode) %功能: 模擬棧的先進後出思路對二值化圖像指定連通區域實現區域生長 %輸入參數: x0,y0表示生長點像素座標,mode表示以多大鄰域進行區域生長,常取mode = 4;mode = 8; %輸出參數: void %做者&時間: 奔跑在湘邊———2016年5月6日 global R BW counter row col zhan = zeros(row*col,2);%建立棧數組 pzhan = 1; %棧計數 zhan(pzhan,1) = x0; zhan(pzhan,2) = y0; R(x0,y0) = 255; counter = 1; if 8 == mode while pzhan > 0 x1 = zhan(pzhan,1);%出棧 y1 = zhan(pzhan,2); pzhan = pzhan - 1; %棧計數減一 for i = -1 : 1 for j = -1 : 1 %生長準則:判斷生長點8鄰域內像素的各自灰度值是否與生長點所在像素灰度值相等 if x1+i > 0 && x1+i <= row && y1+j > 0 && y1+j <= col && BW(x1+i,y1+j) == BW(x1,y1) && R(x1+i,y1+j) ~= R(x1,y1) R(x1+i,y1+j) = R(x1,y1); counter = counter + 1; pzhan = pzhan + 1; %棧計數增一 zhan(pzhan,1) = x1 + i;%入棧 zhan(pzhan,2) = y1 + j; end end end end elseif 4 == mode while pzhan > 0 x1 = zhan(pzhan,1); y1 = zhan(pzhan,2); pzhan = pzhan - 1; for i = -1 : 2 : 1 j = 0; if x1+i > 0 && x1+i <= row && y1+j > 0 && y1+j <= col && BW(x1+i,y1+j) == BW(x1,y1) && R(x1+i,y1+j) ~= R(x1,y1) R(x1+i,y1+j) = R(x1,y1); counter = counter + 1; pzhan = pzhan + 1; zhan(pzhan,1) = x1 + i; zhan(pzhan,2) = y1 + j; end end for j = -1 : 2 : 1 i = 0; if x1+i > 0 && x1+i <= row && y1+j > 0 && y1+j <= col && BW(x1+i,y1+j) == BW(x1,y1) && R(x1+i,y1+j) ~= R(x1,y1) R(x1+i,y1+j) = R(x1,y1); counter = counter + 1; pzhan = pzhan + 1; zhan(pzhan,1) = x1 + i; zhan(pzhan,2) = y1 + j; end end end end end
3、說明
在基於MATLAB7.11.0(R2010b)平臺調用函數模塊fsrRegiongrow時,MATLAB會彈出以下警告
??? Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)
to change the limit. Be aware that exceeding your available stack space can crash MATLAB and/or your computer.
Error in ==> fsrRegiongrow
上述警告表示遞歸次數超出了MATLAB默認值,也就是說待處理的感興趣連通區域像素個數太多(大於500),此時用戶能夠嘗試經過提示的set函數來修改函數遞歸次數,可是本文經過測試發現若是遞歸次數超出1591時(不一樣的平臺該值可能不一樣),MATLAB軟件會自動當即關閉。總之,大量的遞歸調用會創建函數的副本,消耗大量的時間和內存,可是遞歸可使得程序結構清晰易懂,因此本文給出函數遞歸的方法來實現區域生長只是提供一個思路,若是待處理的連通區域像素個數不少,調用fsrRegiongrow1函數就能夠了!fsrRegiongrow1函數模塊是在堆上建立棧數組模擬棧的先進後出思想來實現的,能夠快速的實現區域生長。
4、實驗結果