蚁群算法用于图像边缘提取的主要思想和步骤如下:
-
初始化蚁群:在图像上随机产生一群蚂蚁,定义蚂蚁移动规则和信息素更新公式。
-
蚂蚁爬行建图:让蚂蚁按照一定概率移动规则在图像上爬行,当蚂蚁爬到边缘时,在该位置留下信息素。重复多次迭代。
-
信息素更新:根据蚂蚁移动路径和信息素挥发规则更新各个位置的信息素浓度。信息素主要在边缘位置聚集。
-
图像边缘提取:根据迭代终止条件,当蚂蚁爬行次数达到设定最大值时,提取出信息素浓度大于设定阈值的像素点,连接这些点得到图像边缘。
-
后处理:对提取出的边缘进行后处理,如细化、平滑等消除噪声点,使边缘连贯。
相比传统边缘检测,蚁群算法提取的边缘更连续平滑,适用于图像存在噪声或边缘不清晰的情况。但计算量较大。整体来说,蚁群算法为图像边缘提取提供了一种新的思路。
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');