区域生长:广度优先和深度优先搜索
区域生长算法:从图像的某个点开始,使每块区域扩大,直到被比较的像素与区域像素具有显著差异为止。 区域生长可以用于图像分割。
问题定义: 给定一个生长的起始种子点(starty,startx),作为初始区域; 以一定规则向其邻域生长,即将周围相似的点包含在区域内并作为新的种子继续生长; 直到没有满足规则条件的点时停止。
本代码采用的生长准则:待测像素点和区域平均像素值的差小于等于20,8邻域生长,停止生长条件为区域饱和。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
Image = mpimg.imread('C:/Users/Jichen/Downloads/lotus.jpg')
height = len(Image)
width = len(Image[0])
color = len(Image[0][0])
Redpath = np.zeros([height,width])
for i in range(height):
for j in range(width):
Redpath[i][j] = Image[i][j][0]
def AreaGrowth(Image,starty,startx,neighbors,diff):
'''
从位置(startx,starty)开始,增长区域,直到被比较的像素与区域像素有显著差异为止
Parameters
----------
Image : array
startx : int
starty : int
neighbors : list
邻域
diff : int
当当前像素与区域像素差值小于等于diff时,生长
Returns
-------
生长后的region_array
'''
height = len(Image)
width = len(Image[0])
region = np.zeros([height,width])
region[starty,startx] = 1
region_pixel_num = 1
region_pixel_mean = Image[starty,startx]
flag = np.zeros([height,width]);
flag[starty,startx] = 1
neighbor_num = len(neighbors)
waiting = []
for i in range(neighbor_num):
neighbor = neighbors[i]
y = starty + neighbor[0]
x = startx + neighbor[1]
waiting.append([y,x])
flag[y,x] = 2
pos = 0
waitlen = len(waiting)
while(pos<waitlen):
current = waiting[pos]
pixel = Image[current[0],current[1]]
real_diff = abs(pixel - region_pixel_mean)
if(real_diff <= diff):
region[current[0],current[1]] = 1
region_pixel_mean = region_pixel_mean * region_pixel_num + pixel
region_pixel_num = region_pixel_num + 1
region_pixel_mean = region_pixel_mean / region_pixel_num
for neighbor in neighbors:
neighbor_y = current[0] + neighbor[0]
neighbor_x = current[1] + neighbor[1]
if(neighbor_y>=0 and neighbor_y<height and neighbor_x>=0 and neighbor_x<width and flag[neighbor_y][neighbor_x]==0):
waiting.append([neighbor_y,neighbor_x])
flag[neighbor_y,neighbor_x] = 2
pos += 1
waitlen = len(waiting)
return region
starty = round(height/2)
startx = round(width/2)
neighbors = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]
diff = 20
growth_region = AreaGrowth(Redpath, starty, startx, neighbors, diff)
plt.figure()
subplot(121)
plt.imshow(Redpath)
subplot(122)
plt.imshow(growth_region)
还尝试了一下深度优先搜索,但是内核down了。我不太清楚原因,可能是由于该图像的像素值太接近了,导致搜索深度太深。 这里设置diff=3
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
Image = mpimg.imread('C:/Users/Jichen/Downloads/lotus.jpg')
height = len(Image)
width = len(Image[0])
color = len(Image[0][0])
Redpath = np.zeros([height,width])
for i in range(height):
for j in range(width):
Redpath[i][j] = Image[i][j][1]
def dfs(Image,visited,region,y,x,neighbors,region_pixel_mean,region_num,diff):
height = len(Image)
width = len(Image[0])
pixel = Image[y,x]
if(abs(pixel - region_pixel_mean) <= diff):
region[y,x] = 1
region_pixel_mean = region_pixel_mean*region_num + pixel
region_num = region_num + 1
region_pixel_mean = region_pixel_mean / region_num
for neighbor in neighbors:
yy = y + neighbor[0]
xx = x + neighbor[1]
if(yy>=0 and yy<height and xx>=0 and xx < width and visited[yy,xx]==0):
visited[yy,xx] = 1
dfs(Image,visited,region,yy,xx,neighbors,region_pixel_mean,region_num,diff)
def AreaGrowth2(Image,starty,startx,neighbors,diff):
height = len(Image)
width = len(Image[0])
visited = np.zeros([height,width])
region = np.zeros([height,width])
region[starty,startx] = 1
region_pixel_mean = Image[starty,startx]
region_num = 1
visited[starty,startx] = 1
dfs(Image,visited,region,starty,startx,neighbors,region_pixel_mean,region_num,diff)
return region
starty = round(height/2)
startx = round(width/2)
neighbors = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]
diff = 3
growth_region = AreaGrowth2(Redpath, starty, startx, neighbors, diff)
plt.subplot(121)
plt.imshow(Redpath)
plt.subplot(122)
plt.imshow(growth_region)
|