Opencv之区域生长和分裂

区域生长

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)

文章来源地址https://uudwc.com/A/vmLy1

原文地址:https://blog.csdn.net/hulinhulin/article/details/132890844

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年09月18日 00:44
竞赛 基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉
下一篇 2023年09月18日 00:46