Python实现蚁群算法图像边缘检测

图像课的lab,先声明一下,纯粹是对CV和机器学习感兴趣的外行人自娱自乐,大佬轻喷。聚类+蚁群还在研究,我是拿TSP类比着写的,下面是我实验报告的一部分。
一、中心像素与其8邻域像素灰度差异
TSP问题的两两城市间距离是由城市间的坐标差距计算出来的,以30城市为例,一只蚂蚁处于第i个城市(i=1,2,…30)的时候,有29个城市间距离需要计算。
引申到图像问题上,一只蚂蚁处于中心像素的时候有周围8个点的距离需要计算,此处的距离为灰度差异。
二、下一个像素移动方向概率
依旧以30城市TSP问题为例,蚂蚁处于第i个城市(i=1,2,…30)的时候,下一个访问的城市在剩下29个城市中选择。通过计算概率,可基于轮盘赌算法进行选择,访问过的城市不再访问以此类推。如图,概率的影响因素是距离和信息素浓度。
在这里插入图片描述
引申到图像问题上来,一只蚂蚁在中心像素的位置周围有8个选择,但此处与TSP问题不同,蚂蚁不会以某种顺序遍历所有选择,只会选择其中一个,并成为一只新的蚂蚁,重复之前操作。
三、轮盘赌选择
与TSP问题相似,在蚂蚁选择的下一个访问像素,可由轮盘赌选择决定。
轮盘赌选择的原理是将先前得到的概率相加并分区,如第0区域为p0,第1区域为p0+p1,第n区域为p0+p1+…pn,由于之前的概率是一个加权平均值,p0,p0+p1,…p0+p1+…pn为一个逐渐从0加到1的数据。在0-1的范围内生成一个随机数,如果落到了p0+p1+…pi-1和p0+p1+…pi-1+pi之间,则分到区域i。
轮盘赌选择保证了下一个选择的随机性,之前试过以最大概率的点为下一个访问像素的决策因素,但会导致过早收敛,只能画出一条短线,不能得到相对完整的边缘。
此处轮盘赌会输出0-7之间的8个数,设中心像素坐标为(x0,y0),则0号代表(x0-1,y0-1),1号代表(x0,y0-1),2号代表(x0+1,y0-1),3号代表(x0-1,y0),4号代表(x0+1,y0),5号代表(x0-1,y0+1),6号代表(x0,y0+1),7号代表(x0+1,y0+1)。其中0、1、2号是中心像素上一行的3个像素,3、4号是中心像素同行的2个像素,5、6、7号是中心像素下一行的3个像素。
这块代码可以看看我之前写的:https://blog.csdn.net/pvfeldt/article/details/117841689?spm=1001.2014.3001.5501
四、向下一个像素移动过程
从某个像素移动到下一个像素的过程需要操作的是三个方面:存储蚂蚁路径,计算下一个像素点坐标,更新信息素。
存储蚂蚁路径,方便后续路径的绘制。
下一个像素点的计算中,调用之前的中心像素8邻域灰度差异、下一个像素移动概率、轮盘赌选择,得到下一个方向,按照这个方向得到下一个像素点坐标。下一次调用像素移动过程的时候沿用返回的坐标。如第i次移动过程由(x0,y0)移动到右上方向(轮盘赌输出2的位置)(x0+1,y0-1),则第(i+1)次移动由(x0+1,y0-1)作为起点开始移动。
需要注意的是边界条件:
1.坐标计算时不能超过图像长宽,否则下一次进行访问的时候就会出现数组访问错误。
2.在得到下一像素点坐标的时候,计算其8邻域像素点与中心像素间是否有灰度梯度(此处阈值设为20,若灰度梯度小于20,认为没有差异):如果周围8个点都没有梯度的话说明已经不是边界了;如果周围8个点都是梯度的,很可能该点是噪声点。如果发生这种情况,这条路径将停止于该点,不再继续向下一个像素点移动。
信息素的更新参照下图的原理。此处的边界条件也是灰度梯度,如果无梯度的话,则不再增加该点信息素,后续蚂蚁受到信息素影响访问这个点的概率将减小。
在这里插入图片描述
五、单次迭代过程
与TSP问题一只蚂蚁访问所有城市不同的是,此处单次迭代认为是一批蚂蚁共同画出一条短路径,多条路径组成边缘。重要变量是三个:初始点,信息素,蚂蚁路径。
单次迭代的时候,初始点需要初始化,信息素和蚂蚁路径沿用之前的。
其中,初始化的过程是对于路径初始点,信息素和蚂蚁路径而言的。
边界条件是该点8邻域有灰度梯度,否则可能该点画不出有效路径,只停留于一点,但计算仍在进行,较为浪费。
信息素和蚂蚁路径矩阵分别置为全1和全0。
六、多次迭代过程
单次迭代过程需要随机生成路径起始点的目的是,可以在图中各处画出短路径,最后通过多次迭代,一起画出即为完整的图像边界。画图用了Matplotlib库。
七、运行结果
1.蚁群算法参数
(这里放个能看得过去的参数,实际报告里还有几个参数对比)
α=1,β=1,rho=0.3
迭代次数2000
蚂蚁个数50
图像重置为200*200大小
2.图像对比
(1)原图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)蚁群算法
突然就有印象派那味儿了。。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
3.运行时间
比Sobel慢,可能还会因为图像大小变大而差距更大。。
好吧,纯粹只是个尝试。。
代码
本来是对比效果的,Sobel也附进去了。
Github:https://github.com/pvfeldt/antColonyEdgeDetection
蚁群TSP问题:https://github.com/pvfeldt/TSP
Over.

以下是基于蚁群算法图像边缘检测Python实现代码: ```python import numpy as np import cv2 # 定义参数 alpha = 1 # 信息素重要程度因子 beta = 2 # 启发函数重要程度因子 rho = 0.1 # 信息素挥发因子 Q = 1 ant_count = 10 gen_count = 100 # 读取图像 img = cv2.imread('test.jpg', 0) # 创建信息素矩阵 pheromone = np.ones_like(img) * 0.1 # 创建启发函数矩阵 heuristic = cv2.Sobel(img, cv2.CV_64F, 1, 1) # 定义蚂蚁类 class Ant: def __init__(self, x, y): self.x = x self.y = y self.path = [] self.tabu = [] def move(self): # 更新禁忌表 self.tabu.append((self.x, self.y)) # 计算概率 p = pheromone[self.x - 1: self.x + 2, self.y - 1: self.y + 2] ** alpha * heuristic[self.x - 1: self.x + 2, self.y - 1: self.y + 2] ** beta p[self.tabu[-1][0] - self.x + 1, self.tabu[-1][1] - self.y + 1] = 0 p = p / np.sum(p) # 轮盘赌选择下一个位置 next_x, next_y = np.random.choice(range(self.x - 1, self.x + 2), p=p[:, 0]) , np.random.choice(range(self.y - 1, self.y + 2), p=p[0, :]) # 更新信息素 pheromone[self.x, self.y] = (1 - rho) * pheromone[self.x, self.y] + rho * Q self.path.append((next_x, next_y)) self.x, self.y = next_x, next_y # 初始化蚂蚁群 ants = [Ant(img.shape[0] // 2, img.shape[1] // 2) for _ in range(ant_count)] # 迭代搜索 for _ in range(gen_count): for ant in ants: while True: ant.move() if ant.x < 1 or ant.x > img.shape[0] - 2 or ant.y < 1 or ant.y > img.shape[1] - 2: break # 计算路径长度 path_length = 0 for i in range(len(ant.path) - 1): path_length += np.sqrt((ant.path[i][0] - ant.path[i + 1][0]) ** 2 + (ant.path[i][1] - ant.path[i + 1][1]) ** 2) # 更新信息素 for i in range(len(ant.tabu) - 1): pheromone[ant.tabu[i][0], ant.tabu[i][1]] = (1 - rho) * pheromone[ant.tabu[i][0], ant.tabu[i][1]] + rho * (Q / path_length) # 重置蚂蚁 ant.x, ant.y = img.shape[0] // 2, img.shape[1] // 2 ant.path = [] ant.tabu = [] # 提取边缘 edge = np.zeros_like(img) for ant in ants: for i in range(len(ant.path) - 1): edge[ant.path[i][0], ant.path[i][1]] = 255 # 显示边缘图像 cv2.imshow('Edge Detection', edge) cv2.waitKey(0) ``` 需要注意的是,此代码仅为演示基于蚁群算法图像边缘检测实现方式,并不保证其在所有情况下都能取得良好效果。实际应用中,需要根据具体情况进行调整和优化。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值