Selective Search算法理解

一、算法简介

(一)前言

在这里插入图片描述
在目标检测算法中,RCNN具有较大的影响力。该模型的架构如上图所示。在RCNN中,为了确定目标的具体位置,使用了Selective Search算法,从原始图像中提取2000左右个候选区域,然后再将这些候选区域输入到后续架构中,确定目标的具体位置。
关于RCNN算法的讲解,可参考:
R-CNN(Region-based Convolutional Neural Network)论文解读

(二)算法思路

算法分为如下几个大步:

  1. 生成原始的区域集R(利用felzenszwalb算法)
  2. 计算区域集R里每个相邻区域的相似度S={s1,s2,…}
  3. 找出相似度最高的两个区域,将其合并为新集,添加进R
  4. 从S中移除所有与第3步中有关的子集
  5. 计算新集与所有子集的相似度
  6. 跳至第三步,不断循环,合并,直至S为空(到不能再合并时为止)
    在这里插入图片描述

(三)Python源码分析

1、主函数:selective_search

(1)作用
  • 通过图像分割的方法,从原始图像中提取小区域。
(2)输入
  • im_orig
    原始图片,数据类型为ndarray。
  • scale
    图像分割的集群程度。
    值越大,意味集群程度越高,分割的越少,获得子区域越大,默认为1。
    数据类型为int。
  • sigma
    图像分割前,会先对原图像进行高斯滤波去噪,sigma即为高斯核的大小,默认为0.8。
    数据类型为float。
  • min_size
    最小的区域像素点个数。当小于此值时,图像分割的计算就停止,默认为20。
    数据类型为int。
(3)输出
  • img
    具有区域标签的图片,数据类型为ndarray。
    img数组的形状为(im_orig_height, im_orig_width, 4)
    其中存储的像素信息为:[r, g, b, (region)],region是指区域标签。
  • regions
    区域列表
    regions的结构如下:
    [
    {‘rect’: (x_l, y_d, width, height), ‘size’: size, ‘labels’: labels_list},

    ]
    变量名注释:
    ‘rect’:
    x_l:区域左下角的x值;
    y_d:区域左下角的y值;
    width:区域的宽;
    height:区域的高。
    通过这四个值,我们就能够确定区域的大小及位置。
    ‘size’:区域的尺寸。
    ‘labels’:区域的标签,是列表。
(4)源码
def selective_search(
        im_orig, scale=1.0, sigma=0.8, min_size=50):
    '''Selective Search
    Parameters
    ----------
        im_orig : ndarray
            Input image
        scale : int
            Free parameter. Higher means larger clusters in felzenszwalb segmentation.
        sigma : float
            Width of Gaussian kernel for felzenszwalb segmentation.
        min_size : int
            Minimum component size for felzenszwalb segmentation.
    Returns
    -------
        img : ndarray
            image with region label
            region label is stored in the 4th value of each pixel [r,g,b,(region)]
        regions : array of dict
            [
                {
                    'rect': (left, top, width, height),
                    'labels': [...],
                    'size': component_size
                },
                ...
            ]
    '''
    assert im_orig.shape[2] == 3, "3ch image is expected"
 
    # load image and get smallest regions
    # region label is stored in the 4th value of each pixel [r,g,b,(region)]
    img = _generate_segments(im_orig, scale, sigma, min_size)
 
    if img is None:
        return None, {}
 
    imsize = img.shape[0] * img.shape[1]
    R = _extract_regions(img)
 
    # extract neighbouring information
    neighbours = _extract_neighbours(R)
 
    # calculate initial similarities
    S = {}
    for (ai, ar), (bi, br) in neighbours:
        S[(ai, bi)] = _calc_sim(ar, br, imsize)
 
    # hierarchal search
    while S != {}:
 
        # get highest similarity
        i, j = sorted(S.items(), key=lambda i: i[1])[-1][0]
 
        # merge corresponding regions
        t = max(R.keys()) + 1.0
        R[t] = _merge_regions(R[i], R[j])
 
        # mark similarities for regions to be removed
        key_to_delete = []
        for k, v in list(S.items()):
            if (i in k) or (j in k):
                key_to_delete.append(k)
 
        # remove old similarities of related regions
        for k in key_to_delete:
            del S[k]
 
        # calculate similarity set with the new region
        for k in [a for a in key_to_delete if a != (i, j)]:
            n = k[1] if k[0] in (i, j) else k[0]
            S[(t, n)] = _calc_sim(R[t], R[n], imsize)
 
    regions = []
    for k, r in list(R.items()):
        regions.append({
            'rect': (
                r['min_x'], r['min_y'],
                r['max_x'] - r['min_x'], r['max_y'] - r['min_y']),
            'size': r['size'],
            'labels': r['labels']
        })
 
    return img, regions
(5)函数理解

算法实现过程:

  • 先判断图像的颜色通道数是否为3。
  • 使用_generate_segments函数,生成具有区域标签的图片。
  • 使用_extract_regions函数,获得原始区域集R(R中的每个元素都包含了该区域的位置,尺寸,颜色特征,纹理特征等信息)。
  • 使用_extract_neighbours函数,获得原始区域集R中相交的区域。
  • 使用_calc_sim函数计算两个原始区域集R中相交区域的相似度S。
  • 从S中找出相似度最大的区域对(设为(a, b)),使用_merge_regions函数将其合并为新的区域(设为c),添加进R。
  • 从S中移除所有与上一步中相关的子集,即将所有包含a或b的区域对(设为(a, x),(b, y),(a, b))及对应的相似度,从S中移除。
  • 计算新集与所有子集的相似度,即分别计算区域c与x,y的相似度,并将(c, x): similarity_1和(c, y): similarity_2添加到S中。
  • 不断循环执行后三步,直至S为空。
    我们将后三步放在生成新区域部分进行讲解。
  • 完成上述操作后,我们得到了完整的区域集R’。
  • 从R’中提取我们所需的信息,存入列表regions中。
    此部分我们放入R’信息提取部分进行讲解。
  • 将具有区域标签的图片img和区域集列表regions返回。

2、_generate_segments

(1)作用

使用felzenszwalb图像分割算法,生成原始区域集。

(2)输入
  • im_orig
    原始图片。
    数据类型为ndarray。
  • scale
    图像分割的集群程度。
    值越大,意味集群程度越高,分割的越少,获得子区域越大。
    数据类型为int。
  • sigma
    图像分割前,会先对原图像进行高斯滤波去噪,sigma即为高斯核的大小。
    数据类型为float。
  • min_size
    最小的区域像素点个数。
    当小于此值时,图像分割的计算就停止。
    数据类型为int。
(3)输出
  • img
    具有区域标签的图片,数据类型为ndarray。
    img数组的形状为(im_orig_height, im_orig_width, 4)
    其中存储的像素信息为:[r, g, b, (region)],region是指区域标签。
(4)源码
def _generate_segments(im_orig, scale, sigma, min_size):
    """
        segment smallest regions by the algorithm of Felzenswalb and
        Huttenlocher
    """
    img = []
    # 分割图片,得到图片中每个像素值对应的区域标签
    im_mask = skimage.segmentation.felzenszwalb(
        skimage.util.img_as_float(im_orig), scale=scale, sigma=sigma,
        min_size=min_size)
 
    # 将每个像素的区域标签与RGB值合并,构成四维张量
    # merge mask channel
  • 7
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值