前言
区域生长算法是一种基于像素相似性的图像分割方法,其基本思路是从给定的“种子点”开始,通过逐步添加与该点相似的像素来扩展区域,直到满足一定条件为止。
一、区域生长算法是什么?
区域生长算法是一种基于像素相似性的图像分割方法,其基本思路是从给定的“种子点”开始,通过逐步添加与该点相似的像素来扩展区域,直到满足一定条件为止。
具体实现步骤如下:
1、 选择一个种子点作为算法的起始点。
2、 根据一定的相似度准则(如灰度值相似度、颜色相似度等)来判断邻域内的像素是否属于同一区域,若满足条件,则将其标记为当前区域中的一部分,并将其加入队列中。
3、 重复执行第二步,直到队列为空或无新的像素被添加进来。
4、 对于不同的连通区域,可以采用不同的标记值进行区分,最终得到分割后的图像。
二、实验思路
首先通过Image.open()方法读取图像并转换为一个Numpy数组,然后建立一个等大小的空矩阵,并在其中设立一个种子点。接着进行区域生长,遍历每个像素,如果当前像素的灰度值与周围像素的平均值之差小于一个给定的阈值,则将其标记为与种子点同一区域的像素,并将其加入队列中。重复进行这个过程,直到所有的相邻像素都被标记为同一区域为止。
最后将生长图像的矩阵与原始图像的矩阵相乘,得到分割后的矩阵,并将其转化为二维图片,可以使用Image.fromarray()和new_im.save()方法进行保存。最后可以使用matplotlib.pyplot库中的plt.imshow()方法将原始图像和分割后的图像在一个画布上展示出来。
1.所使用的库
代码如下(示例):
import cv2
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
2.函数的封装
代码如下(示例):
def region_growing(img, seed,k = 40):
"""
基于区域生长的图像分割算法
:param img: 输入图像(灰度图)
:param seed: 种子点
:param k: 阈值,默认为40
:return: 分割结果(二值图)
"""
# 获取图像尺寸
im_array = np.array(img)
[m, n] = im_array.shape
a = np.zeros((m, n)) # 建立等大小空矩阵
a[seed] = 1 # 设立种子点
#进行生长
flag = 1 # 设立是否判断的小红旗
while flag == 1:
flag = 0
#lim = 种子区域的灰度和/种子区域的个数 :种子区域的平均灰度值
lim = (np.cumsum(im_array * a)[-1]) / (np.cumsum(a)[-1])
#开始生长
for i in range(2, m):
for j in range(2, n):
#找到一开始的种子
if a[i, j] == 1:
#遍历 x-1,x,x+1
for x in range(-1, 2):
# 遍历 y-1,y,y+1
for y in range(-1, 2):
#在所选种子的周围进行遍历
if a[i + x, j + y] == 0:
if (abs(im_array[i + x, j + y] - lim) <= k):#如果遍历的元素跟平均灰度值的差的绝对值在阈值以内就生长
flag = 1
a[i + x, j + y] = 1
data = im_array * a # 矩阵相乘获取生长图像的矩阵
return data
3函数的调用
# 读取图像并转换为灰度图
img = cv2.imread('earth.png',0)
# 进行区域生长分割
result = region_growing(img, (70, 70))
new_im = Image.fromarray(result) #data矩阵转化为二维图片,更接近原图
plt.subplot(1,3,1)
plt.imshow(img,cmap='gray')
plt.title("orginal")
plt.axis('off') # 不显示坐标轴
plt.subplot(1,3,2)
plt.imshow(result,cmap='gray')
plt.title("result")
plt.axis('off') # 不显示坐标轴
plt.subplot(1,3,3)
plt.imshow(new_im,cmap='gray')
plt.title("Image")
plt.axis('off') # 不显示坐标轴
plt.show()
效果图如下: