蚁群算法用于图像边缘提取的主要思想和步骤如下:
-
初始化蚁群:在图像上随机产生一群蚂蚁,定义蚂蚁移动规则和信息素更新公式。
-
蚂蚁爬行建图:让蚂蚁按照一定概率移动规则在图像上爬行,当蚂蚁爬到边缘时,在该位置留下信息素。重复多次迭代。
-
信息素更新:根据蚂蚁移动路径和信息素挥发规则更新各个位置的信息素浓度。信息素主要在边缘位置聚集。
-
图像边缘提取:根据迭代终止条件,当蚂蚁爬行次数达到设定最大值时,提取出信息素浓度大于设定阈值的像素点,连接这些点得到图像边缘。
-
后处理:对提取出的边缘进行后处理,如细化、平滑等消除噪声点,使边缘连贯。
相比传统边缘检测,蚁群算法提取的边缘更连续平滑,适用于图像存在噪声或边缘不清晰的情况。但计算量较大。整体来说,蚁群算法为图像边缘提取提供了一种新的思路。
MATLAB主代码如下:
clc;clear all;close all;%清空环境变量和关闭无关窗口
%% 蚁群算法优化图像边缘检测算法 主程序
filename = 'rice';%图片名称
img=imread([filename '.png']);%读取图片
%% 判断是否彩色图片或者灰度图
if size(img,3)==3%彩图的话要转换为灰度
img=rgb2gray(img);
img=double(img)./255;
else%
img=double(img)./255;
end
nrow, ncol\] = size(img); a=0.5; R=3; deltaI=PixelGradient(img);%根据文献的公式(1)进行计算 deltaE=PixelStatisticalMean(img,R);%根据文献的公式(2)(3)(4)(5)进行计算 Eta=CalculateEta(deltaI,deltaE,a);%根据文献的公式(6进行计算 %% ---蚁群算法参数设置开始--- alpha = 1; % beta = 0.1; % rho = 0.1; % phi = 0.05; % tau0=0.0001; % alpha = 0.5; % % beta = 3; % % rho = 0.2; % % phi = 0.3; % % tau0=0.00001; Tau = tau0.\* ones(size(img)); %信息素初始化 %% ---蚁群算法参数设置结束--- AntNumber = round(sqrt(nrow\*ncol));%蚂蚁个数 AntPosition = zeros(AntNumber, 2); % 初始化记录蚂蚁的位置的矩阵 % 初始化蚂蚁位置 rand('state', sum(clock));%随机种子,防止每次运行都一样 H1 = rand(AntNumber, 2); AntPosition(:,1) = round(1 + (nrow-1) \* H1(:,1)); %行标 AntPosition(:,2) = round(1 + (ncol-1) \* H1(:,2)); %列标 %% ----根据图像的大小进行定义内存长度start---- if nrow\*ncol == 128\*128 MyA = 40; memoryLong = round(rand(1).\*(1.15\*MyA-0.85\*MyA)+0.85\*MyA); % memory length elseif nrow\*ncol == 256\*256 MyA = 30; memoryLong = round(rand(1).\*(1.15\*MyA-0.85\*MyA)+0.85\*MyA); % memory length elseif nrow\*ncol == 512\*512 MyA = 20; memoryLong = round(rand(1).\*(1.15\*MyA-0.85\*MyA)+0.85\*MyA); % memory length end %% ----根据图像的大小进行定义内存长度end----- AntMemory = zeros(AntNumber, memoryLong); if nrow\*ncol == 128\*128 Maxiternum = 300; % 迭代次数 % Maxiternum = 10; elseif nrow\*ncol == 256\*256 Maxiternum = 900; % Maxiternum = 100; elseif nrow\*ncol == 512\*512 Maxiternum = 1500; end runNumber = 3; %进度条 myhand01 = waitbar(0,'正在蚁群算法优化图像边缘检测算法运算......', 'tag', 'TMWWaitbar'); gen03=1; allgen03=runNumber\*Maxiternum\*AntNumber; for gen01 = 1: runNumber%循环3次 deltaTau = zeros(nrow, ncol); for gen02 = 1: Maxiternum deltaTauCurrent = zeros(nrow, ncol); for k001 = 1:AntNumber waitbar(gen03/allgen03,myhand01);%每循环一次更新一次进步条 gen03=gen03+1; RowIndexCurrent = AntPosition(k001,1); ColIndexCurrent = AntPosition(k001,2); % 找出当前节点的领域 i01 = RowIndexCurrent;%行标 j01 = ColIndexCurrent;%列标 NeighborhoodIndex = \[i01-1 j01-1; i01-1 j01; i01-1 j01+1; i01 j01-1; i01 j01+1; i01+1 j01-1; i01+1 j01; i01+1 j01+1\];%当前节点的领域集(8领域): 文献中的"其中, (k,l)∈Ω 表示像素(i, j) 8 邻域的点;" %% 领域节点下标的合法性判断 H1 = NeighborhoodIndex(:,1)\>=1 \& NeighborhoodIndex(:,1)\<=nrow \& NeighborhoodIndex(:,2)\>=1 \& NeighborhoodIndex(:,2)\<=ncol;%逻辑判断式,防止超出 LegalRange = NeighborhoodIndex(H1, :); tempTau = zeros(size(LegalRange,1),1);%邻域信息素矩阵初始化 tempTranProbabilities = zeros(size(LegalRange,1),1);%转移概率矩阵初始化 for kk = 1:size(LegalRange,1) H1 = (LegalRange(kk,1)-1)\*ncol + LegalRange(kk,2); if length(find(AntMemory(k001,:)==H1))==0 %不再蚂蚁的禁忌表内 tempTau(kk) = Eta(LegalRange(kk,1), LegalRange(kk,2)); tempTranProbabilities(kk) = Tau(LegalRange(kk,1), LegalRange(kk,2)); else %在蚂蚁的禁忌表内 tempTau(kk) = 0; tempTranProbabilities(kk) = 0; end end % 如果所有邻域都在禁忌表内,从新计算 if (sum(sum(tempTau))==0) \|\| (sum(sum(tempTranProbabilities))==0) for kk = 1:size(LegalRange,1) H1 = (LegalRange(kk,1)-1)\*ncol + LegalRange(kk,2); tempTau(kk) = Eta(LegalRange(kk,1), LegalRange(kk,2)); tempTranProbabilities(kk) = Tau(LegalRange(kk,1), LegalRange(kk,2)); end end %转移概率:文献公式(7),未考虑w,因为w无意义,分子分母相除没有了 TransitProb = (tempTau.\^alpha) .\* (tempTranProbabilities.\^beta) ./ (sum(sum((tempTau.\^alpha) .\* (tempTranProbabilities.\^beta)))); rand('state', sum(100\*clock)); H1 = find(cumsum(TransitProb)\>=rand(1), 1); NextRowindex = LegalRange(H1,1); NextColIndex = LegalRange(H1,2); if length(NextRowindex) == 0 disp('error'); end AntPosition(k001,1) = NextRowindex; AntPosition(k001,2) = NextColIndex; deltaTauCurrent(AntPosition(k001,1), AntPosition(k001,2)) = 1; %% 更新禁忌表开始 if gen02 \<= memoryLong AntMemory(k001,gen02) = (AntPosition(k001,1)-1)\*ncol + AntPosition(k001,2); elseif gen02 \> memoryLong AntMemory(k001,:) = circshift(AntMemory(k001,:),\[0 -1\]); AntMemory(k001,end) = (AntPosition(k001,1)-1)\*ncol + AntPosition(k001,2); end %% 更新禁忌表结束 Tau(NextRowindex,NextColIndex) = (1-rho).\*Tau(NextRowindex,NextColIndex) + rho\*Eta(NextRowindex,NextColIndex);%信息素局部更新,文献公式(11),(12) end %结束蚂蚁循环 deltaTau = (deltaTau + (deltaTauCurrent\>0))\>0; Tau = (1-phi).\*Tau+phi\*tau0; %信息素全局更新,文献公式(13) end end delete(myhand01);%执行完后删除该进度条 Threshold = seperateIED(Tau); %根据信息素浓度来提取边缘的阀值 disp('蚁群算法优化提取图像边缘算法程序运行结束'); imwrite(uint8(abs((Tau\>=Threshold).\*255-255)), gray(256), \[filename 'ACO.bmp'\], 'bmp');  