【数字图像处理5.2】区域生长算法、分裂合并算法和分水岭分割法 python

实验前言与目的

这些算法都属于【基于形态学的图像分割】这一范畴,我们最终做的一切,都是为了图像分割(比如分成黑白两块,相对提取物体主题,为物体描轮廓…)

编写程序完成以下算法,并进行比较,得出结论。

  1. 区域生长算法
  2. 区域分裂合并算法
  3. 分水岭分割算法

1、区域生长算法

参考:https://blog.csdn.net/weixin_43487953/article/details/97395528

注意

  • 区域生长是一种图像分割方法。
  • 区域生长从某个像素出发,按照一定的准则,逐步加入邻近像素,当满足一定的条件时,区域生长终止,进而实现目标的提取。
  • 区域生长的好坏决定于:1.初始点(种子点)的选取。2.生长准则。3.终止条件。
  • 个人感悟:这个算法平均感觉都挺慢的,我运行一个狗子的图,即使换了不同的种子,平均也在10S~20S之间。

PPT思路

在这里插入图片描述

本程序思路:

  1. 先生成同样大小空白矩阵
  2. 设置一个种子点,通过计算判断周围是否有符合条件新种子,编写在空白矩阵中
  3. 通过循环可以获得含有种子标志的新矩阵,将矩阵与原图相乘可以得到利用区域生长分割出的图像。
    备注:由于代码不长,所以思路主要用备注写代码里了、

输入图像经过区域生成算法之后的效果:
在这里插入图片描述

代码

################################################
#################区域生成算法###################
################################################
def 区域生成法(img):
    img_array = np.array(img)#图片转为数组方便操作

    [m,n]=img_array.shape#返回图片的长和宽

    a = np.zeros((m,n)) #建立等大小空矩阵

    a[70,70]=1 #设立种子点
    k = 40 #设立生长阈值

    isMyArea=1 
    #开始循环遍历周围像素,种子长大。
    while isMyArea==1:
        isMyArea=0
        lim = (np.cumsum(img_array*a)[-1])/(np.cumsum(a)[-1])
        for i in range(2,m):
            for j in range(2,n):
                if a[i,j]==1:
                    for x in range(-1,2):
                        for y in range(-1,2):
                            if a[i+x,j+y]==0:
                                if (abs(img_array[i+x,j+y]-lim)<=k) :
                                    isMyArea = 1
                                    a[i+x,j+y]=1
                                    print("我是区域,我正在生长...")
    data = img_array*a #矩阵相乘获取生长图像的矩阵
    new_img = Image.fromarray(data) #data矩阵转化为二维图片

    return new_img

2、区域分裂合并算法

参考:
https://www.jianshu.com/p/fa573431ef3d

在这里插入图片描述

  • 个人感觉,这个分割算法有点【微积分】那种感觉了。
  • 不用像区域生长一样还要选个“种子点”,算法比较“稳”?

算法的思想总的来说,就是:

  1. 先把图像分成4块
  2. 若这其中的一块符合分裂条件,那么这一块又分裂成4块
  3. 分裂到一定数量时,以每块为中心,检查相邻的各块,满足一定条件,就合并。
  4. 如此循环往复进行分裂和合并的操作。
  5. 最后合并小区,即把一些小块图像的合并到旁边的大块里。

注意

  • 本次切割图像不使用专门的库,而是直接通过控制img[x,y,weight,height]来最原图片的一个个小区域直接操作(具体操作是二值化)。
  • 从最终成像来看,区域分裂与合并算法的确具有一定的连续性,不会出现黑图中夹杂着一丝白丝儿的那种噪声。

效果图
在这里插入图片描述

代码

import numpy as np
import cv2 
import matplotlib.pyplot as plt # plt 用于显示图片


#判断方框是否需要再次拆分为四个
def judge(w0, h0, w, h):
    a = img[h0: h0 + h, w0: w0 + w]
    ave = np.mean(a)
    std = np.std(a, ddof=1)
    count = 0
    total = 0
    for i in range(w0, w0 + w):
        for j in range(h0, h0 + h):
        #注意!我输入的图片数灰度图,所以直接用的img[j,i],RGB图像的话每个img像素是一个三维向量,不能直接与avg进行比较大小。
            if abs(img[j, i] - ave) < 1 * std:
                count += 1
            total += 1
    if (count / total) < 0.95:#合适的点还是比较少,接着拆
        return True
    else:
        return False

##将图像将根据阈值二值化处理,在此默认125
def draw(w0, h0, w, h):
    for i in range(w0, w0 + w):
        for j in range(h0, h0 + h):
            if img[j, i] > 125:
                img
  • 61
    点赞
  • 345
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值