Opencv之区域生长和分裂

2023-09-14 21:19:46

区域生长

1.基本原理

区域生长法是较为基础的一种区域分割方法
它的基本思想我说的通俗些,即是一开始有一个生长点(可以一个像素也可以是一个小区域),从这个生长点开始往外扩充,扩充的意思就是它会把跟自己有相似特征的像素或者区域拉到自己的队伍里,以此壮大自己的势力范围,每次扩大后的势力范围就是一个新的生长点,一直生长一直生长,直到不能生长为止。
所以很容易就能总结出来三个要点:
(1)一个合适的像素或者小区域作为开始的生长点
(2)生长准则,也就是通过什么标准你才能拉他入伙
(3)停止生长的条件 什么时候停止扩充

2.简单例子说明

下面是一个简单的例子:

image.png

3.代码 

import cv2
import numpy as np

####################################################################################


#######################################################################################
class Point(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def getX(self):
        return self.x

    def getY(self):
        return self.y


connects = [
    Point(-1, -1),
    Point(0, -1),
    Point(1, -1),
    Point(1, 0),
    Point(1, 1),
    Point(0, 1),
    Point(-1, 1),
    Point(-1, 0)
]


#####################################################################################
# 计算两个点间的欧式距离
def get_dist(seed_location1, seed_location2):
    l1 = im[seed_location1.x, seed_location1.y]
    l2 = im[seed_location2.x, seed_location2.y]
    count = np.sqrt(np.sum(np.square(l1 - l2)))
    return count


# import Image
im = cv2.imread('./7.jpg')
cv2.imshow('src', im)
im_shape = im.shape
height = im_shape[0]
width = im_shape[1]

print('the shape of image :', im_shape)

# 标记,判断种子是否已经生长
img_mark = np.zeros([height, width])
cv2.imshow('img_mark', img_mark)

# 建立空的图像数组,作为一类
img_re = im.copy()
for i in range(height):
    for j in range(width):
        img_re[i, j][0] = 0
        img_re[i, j][1] = 0
        img_re[i, j][2] = 0
cv2.imshow('img_re', img_re)

# 取一点作为种子点
seed_list = []
seed_list.append(Point(15, 15))
T = 7  # 阈值
class_k = 1  # 类别
# 生长一个类
while (len(seed_list) > 0):
    seed_tmp = seed_list[0]
    # 将以生长的点从一个类的种子点列表中删除
    seed_list.pop(0)

    img_mark[seed_tmp.x, seed_tmp.y] = class_k

    # 遍历8邻域
    for i in range(8):
        tmpX = seed_tmp.x + connects[i].x
        tmpY = seed_tmp.y + connects[i].y

        if (tmpX < 0 or tmpY < 0 or tmpX >= height or tmpY >= width):
            continue
        dist = get_dist(seed_tmp, Point(tmpX, tmpY))
        # 在种子集合中满足条件的点进行生长
        if (dist < T and img_mark[tmpX, tmpY] == 0):
            img_re[tmpX, tmpY][0] = im[tmpX, tmpY][0]
            img_re[tmpX, tmpY][1] = im[tmpX, tmpY][1]
            img_re[tmpX, tmpY][2] = im[tmpX, tmpY][2]
            img_mark[tmpX, tmpY] = class_k
            seed_list.append(Point(tmpX, tmpY))

########################################################################################
# 输出图像
cv2.imshow('OUTIMAGE', img_re)
cv2.waitKey(0)

 区域生长法的优点是计算简单,对于较均匀的连通目标有较好的分割效果。
缺点是需要人为确定种子点,对噪声敏感,可能导致区域内有空洞。另外当目标较大时,分割速度较慢,因此在设计算法时,要尽量提高效率。

区域分裂和聚合

1.基本原理

分裂和聚合
 

image.png


具体来说 举个例子
区域分裂与聚合就是判断一个区域的均值和方差是不是在人为设定的阈值中,如果是的话这个区域分割出来,不是的话就将这个区域分为左上、右上、左下、右下四个部分再递归判断,直到最后结束。

代码

import cv2 as cv
import numpy as np


class region_div:

    def __init__(self, img):
        self.img = img
        self.res = np.zeros(img.shape)

    def region_div_group(self, range1, range2):
        if range1[1] - range1[0] == 0 or range2[1] - range2[0] == 0:
            return

        mean = self.img[range1[0]:range1[1], range2[0]:range2[1]].mean()
        var = self.img[range1[0]:range1[1], range2[0]:range2[1]].var()
        # print(self.img[range1[0]:range1[1],range2[0]:range2[1]])
        # print(range1, range2, var)
        if var < 10:
            self.res[range1[0]:range1[1], range2[0]:range2[1]] = 255
        else:
            if range1[1] - range1[0] >= 2 and range2[1] - range2[0] >= 2:
                self.region_div_group(
                    [range1[0], (range1[0] + range1[1]) // 2],
                    [range2[0], (range2[0] + range2[1]) // 2])
                self.region_div_group(
                    [(range1[0] + range1[1]) // 2, range1[1]],
                    [range2[0], (range2[0] + range2[1]) // 2])
                self.region_div_group(
                    [range1[0], (range1[0] + range1[1]) // 2],
                    [(range2[0] + range2[1]) // 2, range2[1]])
                self.region_div_group(
                    [(range1[0] + range1[1]) // 2, range1[1]],
                    [(range2[0] + range2[1]) // 2, range2[1]])


image = cv.imread('./8.jpg')
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
# print(gray.shape)
# print(gray[0:1, 5:11])
res = np.zeros(gray.shape)
rd = region_div(gray)
rd.region_div_group([0, gray.shape[0]], [0, gray.shape[1]])

res = rd.res
cv.namedWindow("gray")
cv.imshow("gray", gray)
cv.waitKey(0)

cv.namedWindow("res")
cv.imshow("res", res)
cv.waitKey(0)

更多推荐

探索小程序的世界(专栏导读、基础理论)

文章导读一、为什么要学习小程序开发1.1低门槛1.2市场需求1.3创业机会1.4技术发展趋势二、专栏导读2.1实战系列2.2工具系列2.3游戏系列2.4插件系列三、基础理论3.1微信小程序简易教程框架组件API工具开发者工具项目结构3.2app.json配置pageswindowtabbar3.3App.jsonLau

k8备份与恢复-Velero

简介Velero是一款可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷等资源的备份恢复软件。Velero实现的kubernetes资源备份能力,可以轻松实现Kubernetes集群的数据备份和恢复、复制kubernetes集群资源到其他kubernetes集群或者快速复制生产环境到测试环境等功能,这种备份

4. algorithm

algorithm书写1.algorithm2.algorithm2e1.algorithm在LaTeX中,要显示算法,您可以使用algorithm宏包来排版算法,并使用algorithmic宏包来编写算法的伪代码。以下是显示算法的基本步骤:导入宏包:在LaTeX文档的导言区(preamble)中,导入algorith

idea集成tomcat(Smart Tomcate插件安装)

当我们在tomcat上部署好一个webapp后,如果我们要修改代码,就需要重新进行打包和部署,但往往在工作中是需要频繁修改代码,然后再查看成果的,就需要反复的进行打包和部署的过程,这是很麻烦的通过SmartTomcate插件我们就能解决这个问题,可以直接使用idea图形化界面把代码部署到tomcat上达成“一键打包&部

Windows服务器设置Nginx实现分布式服务

1.安装Nginx下载Nginx-1.16.1版本。解压到如下目录:设置环境变量:检查版本:启动nginx.exe,出现黑框一闪而过,进程中出现如下情况代表启动成功:2.搭建模拟HTTP服务下载wiremock-standalone-2.25.1.jar,可以使用Maven配置pom.xml下载。注意下载standal

JavaWeb后端开发 JWT令牌解析 登录校验 通用模板/SpringBoot整合

目录实现思路相关技术的解析​编辑会话跟踪三个方案JWT令牌技术​生成令牌校验令牌登录下发令牌实现思路通过登录成功的标记来检测,在每个接口前做一个标记判断是否登录,若没登录则返回错误信息,并使前端退出.但这样较为繁琐,因此我们可以通过一种统一拦截的技术来拦截所有请求.相关技术的解析会话跟踪的三个方案1.访问cookie的

Nginx替代产品-Tengine健康检测

1、官网地址官网地址:TheTengineWebServer文档地址:文档-TheTengineWebServer健康检测模块:ngx_http_upstream_check_module-TheTengineWebServer2、安装下载wgethttps://tengine.taobao.org/download/

数据中心防雷机柜PDU产品应该怎么选?

PDU防雷插座是针对标准机柜上安装而设计,主要保护机柜内通信、电子等重要设备,避免因过电压和雷电感应而造成设备损坏。该类型PDU将防雷器与电源插板完美组合,配有多路输出插孔,兼容多国插头标准,可同时保护多路电源,使用安全可靠,简单方便,可更换式防雷模块、维护方便等优点。随着现代科技的发展和社会的进步,各行各业在不断地引

E. Moment of Bloom

Problem-E-Codeforces思路:这个题看到之后想到了不可能的情况,就是如果度为奇数就一定不可能实现都是偶数,但是后面就不知道怎么搞了。正解是欧拉定理的应用把算是,首先对于给定的q个要求,我们从a->b连一条边,如果此时生成的图由许多个欧拉回路组成,并且我们还知道给定的这个图是联通的,那么我们就可以生成一颗

阿里云产品试用系列-函数计算 FC

函数计算(FunctionCompute)是一个事件驱动的全托管Serverless计算服务,您无需管理服务器等基础设施,只需编写代码并上传,函数计算会为您准备好计算资源,并以弹性、可靠的方式运行您的代码。如上所示,在阿里云首页访问免费试用函数计算FC云计算产品如上所示,设置内存资源以及计算资源的容量如上所示,在阿里云

如何获取美团的热门商品和服务

导语美团是中国最大的生活服务平台之一,提供了各种各样的商品和服务,如美食、酒店、旅游、电影、娱乐等。如果你想了解美团的热门商品和服务,你可以使用爬虫技术来获取它们。本文将介绍如何使用Python和BeautifulSoup库来编写一个简单的爬虫程序,以及如何使用爬虫代理来提高爬虫的效率和稳定性。概述爬虫技术是一种通过网

热文推荐