关于图像分割:图像分割二区域生长和区域分裂

5次阅读

共计 3728 个字符,预计需要花费 10 分钟才能阅读完成。

上文曾经说到,图像宰割就是获取你感兴趣的物体或区域的过程。
图像宰割中,基于区域的办法是以间接寻找区域为根底的宰割技术

一. 区域成长

1. 基本原理

区域成长法是较为根底的一种区域分割办法
它的根本思维我说的艰深些,即是一开始有一个生长点(能够一个像素也能够是一个小区域),从这个生长点开始往外裁减,裁减的意思就是它会把跟本人有类似特色的像素或者区域拉到本人的队伍里,以此壮大本人的势力范围,每次扩充后的势力范围就是一个新的生长点,始终成长始终成长,直到不能成长为止。
所以很容易就能总结进去三个要点:
(1)一个适合的像素或者小区域作为开始的生长点
(2)成长准则,也就是通过什么规范你能力拉他入伙
(3)进行成长的条件 什么时候进行裁减

2. 简略例子阐明

上面是一个简略的例子:

此例子截图来自:
https://blog.csdn.net/webzhuc…

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)

左边的图让我想起来 离别巨匠外面邓超演的拉不拉卡(反正就是很黑)hhh

区域成长法的长处是计算简略,对于较平均的连通指标有较好的宰割成果。
毛病是须要人为确定种子点,对噪声敏感,可能导致区域内有空洞。另外当指标较大时,宰割速度较慢,因而在设计算法时,要尽量提高效率。

二. 区域决裂和聚合

1. 基本原理

决裂和聚合

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

2. 例子阐明

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://blog.csdn.net/py18447…
感觉边界很含糊
决裂合并法的要害是决裂合并准则的设计。这种办法对简单图像的宰割成果较好,但算法较简单,计算量大,决裂还可能毁坏区域的边界。

正文完
 0