目标检测之选择性搜索:Selective Search

news2024/9/20 6:24:46

文章目录

  • 一.选择性搜索的具体算法
  • 二.保持多样性的策略
  • 三.给区域打分
  • 四.选择性搜索性能评估
  • 五.代码实现

论文地址: https://www.koen.me/research/selectivesearch/
代码地址: https://github.com/AlpacaDB/selectivesearch
参考: https://www.cnblogs.com/zyly/p/9259392.html

一.选择性搜索的具体算法

输入:(彩色)图片
输出:候选的目标位置集合

算法:
利用切分方法得到候选的区域集合R = {r1,r2,…,rn}
初始化相似集合S = ϕ
foreach 遍历邻居区域对(ri,rj) do
    计算相似度s(ri,rj)
    S = S  ∪ s(ri,rj)
while S not=ϕ do
    从S中得到最大的相似度s(ri,rj)=max(S)
    合并对应的区域rt = ri ∪ rj
    移除ri对应的所有相似度:S = S\s(ri,r*)
    移除rj对应的所有相似度:S = S\s(r*,rj)
    计算rt对应的相似度集合St
    S = S ∪ St
    R = R ∪ rt
L = R中所有区域对应的边框

首先通过基于图的图像分割方法初始化原始区域,就是将图像分割成很多很多的小块。然后我们使用贪心策略,计算每两个相邻的区域的相似度,然后每次合并最相似的两块,直到最终只剩下一块完整的图片。然后这其中每次产生的图像块包括合并的图像块我们都保存下来,这样就得到图像的分层表示了呢。那我们如何计算两个图像块的相似度呢?

二.保持多样性的策略

区域合并采用了多样性的策略,如果简单采用一种策略很容易错误合并不相似的区域,比如只考虑纹理时,不同颜色的区域很容易被误合并。选择性搜索采用三种多样性策略来增加候选区域以保证召回:

  • 多种颜色空间,考虑RGB、灰度、HSV及其变种等
  • 多种相似度度量标准,既考虑颜色相似度,又考虑纹理、大小、重叠情况等。
  • 通过改变阈值初始化原始区域,阈值越大,分割的区域越少。
  1. 颜色空间变换

    通过色彩空间变换,将原始色彩空间转换到多达八中的色彩空间。作者采用了8中不同的颜色方式,主要是为了考虑场景以及光照条件等。这个策略主要应用于图像分割算法中原始区域的生成(两个像素点的相似度计算时,计算不同颜色空间下的两点距离)。主要使用的颜色空间有:

    (1)RGB

    (2)灰度I

    (3)Lab

    (4)rgI(归一化的rg通道加上灰度)

    (5)HSV

    (6)rgb(归一化的RGB)

    (7)C

    (8)H(HSV的H通道)

    在这里插入图片描述

  2. 区域相似度计算

    我们在计算多种相似度的时候,都是把单一相似度的值归一化到[0,1]之间,1表示两个区域之间相似度最大。

    • 颜色相似度

      使用L1-norm归一化获取图像每个颜色通道的25 bins的直方图,这样每个区域都可以得到一个75维的向量 { c i 1 , ⋯   , c i n } \left\{c_{i}^{1}, \cdots, c_{i}^{n}\right\} {ci1,,cin},区域之间颜色相似度通过下面的公式计算:

    s colour  ( r i , r j ) = ∑ k = 1 n min ⁡ ( c i k , c j k ) s_{\text {colour }}\left(r_{i}, r_{j}\right)=\sum_{k=1}^{n} \min \left(c_{i}^{k}, c_{j}^{k}\right) scolour (ri,rj)=k=1nmin(cik,cjk)

    上面这个公式可能你第一眼看过去看不懂,那咱们打个比方,由于 { c i 1 , ⋯   , c i n } \left\{c_{i}^{1}, \cdots, c_{i}^{n}\right\} {ci1,,cin}是归一化后值,每一个颜色通道的直方图累加和为1.0,三个通道的累加和就为3.0,如果区域和区域直方图完全一样,则此时颜色相似度最大为3.0,如果不一样,由于累加取两个区域bin的最小值进行累加,当直方图差距越大,累加的和就会越小,即颜色相似度越小。

    在区域合并过程中使用需要对新的区域进行计算其直方图,计算方法:

    C t = size ⁡ ( r i ) × C i + size ⁡ ( r j ) × C j size ⁡ ( r i ) + size ⁡ ( r j ) C_{t}=\frac{\operatorname{size}\left(r_{i}\right) \times C_{i}+\operatorname{size}\left(r_{j}\right) \times C_{j}}{\operatorname{size}\left(r_{i}\right)+\operatorname{size}\left(\mathrm{r}_{j}\right)} Ct=size(ri)+size(rj)size(ri)×Ci+size(rj)×Cj

    • 纹理相似度

      这里的纹理采用SIFT-Like特征。具体做法是对每个颜色通道的8个不同方向计算方差σ=1的高斯微分(Gaussian Derivative),使用L1-norm归一化获取图像每个颜色通道的每个方向的10 bins的直方图,这样就可以获取到一个240(10x8x3)维的向量 T i = { t i 1 , ⋯   , t i n } T_{i}=\left\{t_{i}^{1}, \cdots, t_{i}^{n}\right\} Ti={ti1,,tin},区域之间纹理相似度计算方式和颜色相似度计算方式类似,合并之后新区域的纹理特征计算方式和颜色特征计算相同:

    s texture  ( r i , r j ) = ∑ k = 1 n min ⁡ ( t i k , t j k ) s_{\text {texture }}\left(r_{i}, r_{j}\right)=\sum_{k=1}^{n} \min \left(t_{i}^{k}, t_{j}^{k}\right) stexture (ri,rj)=k=1nmin(tik,tjk)

    • 优先合并小的区域

      如果仅仅是通过颜色和纹理特征合并的话,很容易使得合并后的区域不断吞并周围的区域,后果就是多尺度只应用在了那个局部,而不是全局的多尺度。因此我们给小的区域更多的权重,这样保证在图像每个位置都是多尺度的在合并。下面的公式表示,两个区域越小,其相似度越大,越接近1。

    s size  ( r i , r j ) = 1 − size ⁡ ( r i ) + size ⁡ ( r j ) size ⁡ ( i m ) s_{\text {size }}\left(r_{i}, r_{j}\right)=1-\frac{\operatorname{size}\left(r_{i}\right)+\operatorname{size}\left(\mathrm{r}_{\mathrm{j}}\right)}{\operatorname{size}(\mathrm{im})} ssize (ri,rj)=1size(im)size(ri)+size(rj)

    • 区域的合适度距离

      如果区域 r i r_{i} ri包含在 r j r_{j} rj内,我们首先应该合并,另一方面,如果 r i r_{i} ri很难与 r j r_{j} rj相接,他们之间会形成断崖,不应该合并在一块。这里定义区域的合适度距离主要是为了衡量两个区域是否更加“吻合”,其指标是合并后的区域的Bounding Box(能够框住区域的最小矩形 B B i j BB_{ij} BBij)越小,其吻合度越高,即相似度越接近1。其计算方式:

    fill ⁡ ( r i , r j ) = 1 − size ⁡ ( B B i j ) − size ⁡ ( r i ) − size ⁡ ( r i ) size ⁡ ( i m ) \operatorname{fill}\left(r_{i}, r_{j}\right)=1-\frac{\operatorname{size}\left(B B_{i j}\right)-\operatorname{size}\left(r_{i}\right)-\operatorname{size}\left(r_{i}\right)}{\operatorname{size}(i m)} fill(ri,rj)=1size(im)size(BBij)size(ri)size(ri)

    • 合并上面四种相似度,其中$a_{i} \in{0,1}

s ( r i , r j ) = a 1 s colour  ( r i , r j ) + a 2 s texture  ( r i , r j ) + a 3 s size  ( r i , r j ) + a 4 s fill  ( r i , r j ) \begin{aligned} s\left(r_{i}, r_{j}\right)=& a_{1} s_{\text {colour }}\left(r_{i}, r_{j}\right)+a_{2} s_{\text {texture }}\left(r_{i}, r_{j}\right)+\\ & a_{3} s_{\text {size }}\left(r_{i}, r_{j}\right)+a_{4} s_{\text {fill }}\left(r_{i}, r_{j}\right) \end{aligned} s(ri,rj)=a1scolour (ri,rj)+a2stexture (ri,rj)+a3ssize (ri,rj)+a4sfill (ri,rj)

三.给区域打分

通过上述的步骤我们能够得到很多很多的区域,但是显然不是每个区域作为目标的可能性都是相同的,因此我们需要衡量这个可能性,这样就可以根据我们的需要筛选区域建议个数啦。
这篇文章做法是,给予最先合并的图片块较大的权重,比如最后一块完整图像权重为1,倒数第二次合并的区域权重为2以此类推。但是当我们策略很多,多样性很多的时候呢,这个权重就会有太多的重合了,排序不好搞啊。文章做法是给他们乘以一个随机数,毕竟3分看运气嘛,然后对于相同的区域多次出现的也叠加下权重,毕竟多个方法都说你是目标,也是有理由的嘛。这样我就得到了所有区域的目标分数,也就可以根据自己的需要选择需要多少个区域了。

四.选择性搜索性能评估

自然地,通过算法计算得到的包含物体的Bounding Boxes与真实情况(ground truth)的窗口重叠越多,那么算法性能就越好。这时使用的指标是平均最高重叠率ABO(Average Best Overlap)。对于每个固定的类别 c,每个真实情况(ground truth)表示为 g i c ∈ G c g_{i}^{c} \in G^{c} gicGc ,令计算得到的位置假设 L L L中的每个值 L j L_j Lj,那么 ABO的公式表达为:

A B O = 1 ∣ G c ∣ ∑ g i c ∈ G c max ⁡ l j ∈ L O v e r l a p ( g i c , l j ) \mathrm{ABO}=\frac{1}{\left|G^{c}\right|} \sum_{g_{i}^{c} \in G^{c}} \max _{l_{j} \in L} \mathrm{Overlap}\left(g_{i}^{c}, l_{j}\right) ABO=Gc1gicGcljLmaxOverlap(gic,lj)

  • 重叠率的计算方式:

 Overlap  ( g i c , l j ) = area ⁡ ( g i c ) ∩ area ⁡ ( l j ) area ⁡ ( g i c ) ∪ area ⁡ ( l j ) \text { Overlap }\left(g_{i}^{c}, l_{j}\right)=\frac{\operatorname{area}\left(g_{i}^{c}\right) \cap \operatorname{area}\left(\mathrm{l}_{\mathrm{j}}\right)}{\operatorname{area}\left(g_{i}^{c}\right) \cup \operatorname{area}\left(\mathrm{l}_{\mathrm{j}}\right)}  Overlap (gic,lj)=area(gic)area(lj)area(gic)area(lj)

上面结果给出的是一个类别的ABO,对于所有类别下的性能评价,很自然就是使用所有类别的ABO的平均值MABO(Mean Average Best Overlap)来评价。

  1. 单一策略评估

    我们可以通过改变多样性策略中的任何一种,评估选择性搜索的MABO性能指标。论文中采取的策略如下:

    • 使用RGB色彩空间(基于图的图像分割会利用不同的色彩进行图像区域分割)
    • 采用四种相似度计算的组合方式
    • 设置图像分割的阈值k=50

    然后通过改变其中一个策略参数,获取MABO性能指标如下表(第一列为改变的参数,第二列为MABO值,第三列为获取的候选区的个数):

    在这里插入图片描述

    表中左侧为不同的相似度组合,单独的,我们可以看到纹理相似度表现最差,MABO为0.581,其他的MABO值介于0.63和0.64之间。当使用多种相似度组合时MABO性能优于单种相似度。表的右上角表名使用HSV颜色空间,有463个候选区域,而且MABO值最大为0.693。表的右下角表名使用较小的阈值,会得到更多的候选区和较高的MABO值。

  2. 多样性策略组合

    我们使用贪婪的搜索算法,把单一策略进行组合,会获得较高的MABO,但是也会造成计算成本的增加。下表给出了三种组合的MABO性能指标:

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

    上图中的绿色边框为对象的标记边框,红色边框为我们使用 ‘Quality’ Selective Search算法获得的Overlap最高的候选框。可以看到我们这个候选框和真实标记非常接近。
    下表为和其它算法在VOC 2007测试集上的比较结果:

    在这里插入图片描述

    下图为各个算法在选取不同候选区数量,Recall和MABO性能的曲线图,从计算成本、以及性能考虑,Selective Search Fast算法在2000个候选区时,效果较好。

    在这里插入图片描述

五.代码实现

import skimage.io
import skimage.feature
import skimage.color
import skimage.transform
import skimage.util
import skimage.segmentation
import numpy


def _generate_segments(im_orig, scale, sigma, min_size):
    """
    通过(Felzenswalb and Huttenlocher)的算法来分割最小的区域
    :param im_orig: ndarray 输入图像:(宽度,高度,3)或(宽度,高度)即灰度图或者rgb三通道彩色图
    [[[...]  [[...]  [[...]
      [...]   [...]   [...]
      [...]]  [...]]  [...]]]
    :param scale: float 设置观察级别,规模越大意味着越来越小的部分
    :param sigma: float 高斯核的直径,用于在分割之前平滑图像
    :param min_size: int 最小组件大小,使用后处理强制执行
    :return: im_orig:
    """
    # 使用(Felzenswalb and Huttenlocher)的算法来对图像进行初始的图像区域分割
    im_mask = skimage.segmentation.felzenszwalb(
        skimage.util.img_as_float(im_orig), scale=scale, sigma=sigma,
        min_size=min_size)
    # 将初始分割好的数据添加到图像数据中,图像数据成为4维数组
    im_orig = numpy.append(
        im_orig, numpy.zeros(im_orig.shape[:2])[:, :, numpy.newaxis], axis=2)
    im_orig[:, :, 3] = im_mask
    return im_orig


def _sim_colour(r1, r2):
    """
    计算颜色相似度
    :param r1:候选区域r1
    :param r2:候选区域r2
    :return:[0,3]之间的数值
    """
    return sum([min(a, b) for a, b in zip(r1["hist_c"], r2["hist_c"])])


def _sim_texture(r1, r2):
    """
    计算文理相似度
    :param r1:候选区域r1
    :param r2:候选区域r2
    :return:[0,3]之间的数值
    """
    return sum([min(a, b) for a, b in zip(r1["hist_t"], r2["hist_t"])])


def _sim_size(r1, r2, imsize):
    """
    计算候选区域大小相似度
    :param r1:候选区域r1
    :param r2:候选区域r2
    :param imsize:原图像像素数
    :return:[0,1]之间的数值
    """
    return 1.0 - (r1["size"] + r2["size"]) / imsize


def _sim_fill(r1, r2, imsize):
    """
    计算候选区域的距离合适度相似度
    :param r1:候选区域r1
    :param r2:候选区域r2
    :param imsize:原图像像素数
    :return:[0,1]之间的数值
    """
    bbsize = (
            (max(r1["max_x"], r2["max_x"]) - min(r1["min_x"], r2["min_x"]))
            * (max(r1["max_y"], r2["max_y"]) - min(r1["min_y"], r2["min_y"]))
    )
    return 1.0 - (bbsize - r1["size"] - r2["size"]) / imsize


def _calc_sim(r1, r2, imsize):
    """
    计算两个候选区域的相似度,权重系数默认都是1
    :param r1:候选区域r1
    :param r2:候选区域r2
    :param imsize:原图片像素数
    :return:[0,1]之间的数值
    """
    return (_sim_colour(r1, r2) + _sim_texture(r1, r2)
            + _sim_size(r1, r2, imsize) + _sim_fill(r1, r2, imsize))


def _calc_colour_hist(img):
    """
    使用L1-norm归一化获取图像每个颜色通道的25 bins的直方图,这样每个区域都可以得到一个75维的向量
    calculate colour histogram for each region
    the size of output histogram will be BINS * COLOUR_CHANNELS(3)
    number of bins is 25 as same as [uijlings_ijcv2013_draft.pdf]
    extract HSV
    :param img:ndarray类型, 形状为候选区域像素数 x 3(h,s,v)
    :return:一维的ndarray类型,长度为75
    """
    BINS = 25
    hist = numpy.array([])
    for colour_channel in (0, 1, 2):
        # extracting one colour channel
        c = img[:, colour_channel]
        # calculate histogram for each colour and join to the result
        hist = numpy.concatenate(
            [hist] + [numpy.histogram(c, BINS, (0.0, 255.0))[0]])
    # L1 normalize
    hist = hist / len(img)
    return hist


def _calc_texture_gradient(img):
    """
    calculate texture gradient for entire image
    The original SelectiveSearch algorithm proposed Gaussian derivative
    for 8 orientations, but we use LBP instead.
    output will be [height(*)][width(*)]
    :param img:
    :return:
    """
    ret = numpy.zeros((img.shape[0], img.shape[1], img.shape[2]))
    for colour_channel in (0, 1, 2):
        ret[:, :, colour_channel] = skimage.feature.local_binary_pattern(
            img[:, :, colour_channel], 8, 1.0)
    return ret


def _calc_texture_hist(img):
    """
        calculate texture histogram for each region
        calculate the histogram of gradient for each colours
        the size of output histogram will be
            BINS * ORIENTATIONS * COLOUR_CHANNELS(3)
    """
    BINS = 10
    hist = numpy.array([])
    for colour_channel in (0, 1, 2):
        # mask by the colour channel
        fd = img[:, colour_channel]
        # calculate histogram for each orientation and concatenate them all
        # and join to the result
        hist = numpy.concatenate(
            [hist] + [numpy.histogram(fd, BINS, (0.0, 1.0))[0]])
    # L1 Normalize
    hist = hist / len(img)
    return hist


def _extract_regions(img):
    """
    提取每一个候选区域的信息   比如类别(region)为5的区域表示的是一只猫的选区,这里就是提取这只猫的边界框,左上角后右下角坐标
    args:
        img: ndarray类型,形状为height x width x 4,每一个像素的值为 [r,g,b,(region)]
    return :
        R:dict 每一个元素对应一个候选区域, 每个元素也是一个dict类型
                              {min_x:边界框的左上角x坐标,
                              min_y:边界框的左上角y坐标,
                              max_x:边界框的右下角x坐标,
                              max_y:边界框的右下角y坐标,
                              size:像素个数,
                              hist_c:颜色的直方图,
                              hist_t:纹理特征的直方图,}
    """
    R = {}

    hsv = skimage.color.rgb2hsv(img[:, :, :3])  # 获取hsv图像
    # 1:获取每个像素点所在的区域
    for y, i in enumerate(img):
        for x, (r, g, b, l) in enumerate(i):
            # 判断像素点所在区域是否已经添加,还没有添加的话创建一个新的区域
            if l not in R:
                R[l] = {
                    "min_x": 0xffff, "min_y": 0xffff,
                    "max_x": 0, "max_y": 0, "labels": [l]}
            # 创建可以隆纳下区域的最大的盒子(bounding box)
            if R[l]["min_x"] > x:
                R[l]["min_x"] = x
            if R[l]["min_y"] > y:
                R[l]["min_y"] = y
            if R[l]["max_x"] < x:
                R[l]["max_x"] = x
            if R[l]["max_y"] < y:
                R[l]["max_y"] = y

    tex_grad = _calc_texture_gradient(img)  # 2:计算文理梯度
    # 3:计算每个区域的颜色直方图
    for k, v in R.items():
        # colour histogram
        masked_pixels = hsv[:, :, :][img[:, :, 3] == k]  # (img[:, :, 3] == k返回的是一个二维坐标的集合)
        R[k]["size"] = len(masked_pixels / 4)
        R[k]["hist_c"] = _calc_colour_hist(masked_pixels)
        # texture histogram
        R[k]["hist_t"] = _calc_texture_hist(tex_grad[:, :][img[:, :, 3] == k])
    return R


def _extract_neighbours(regions):
    """
    提取 邻居候选区域对(ri,rj)(即两两相交)
    args:
        regions:dict 每一个元素都对应一个候选区域
    return:
        返回一个list,每一个元素都对应一个邻居候选区域对
    """

    # 判断两个候选区域是否相交
    def intersect(a, b):
        if (a["min_x"] < b["min_x"] < a["max_x"]
            and a["min_y"] < b["min_y"] < a["max_y"]) or (
                a["min_x"] < b["max_x"] < a["max_x"]
                and a["min_y"] < b["max_y"] < a["max_y"]) or (
                a["min_x"] < b["min_x"] < a["max_x"]
                and a["min_y"] < b["max_y"] < a["max_y"]) or (
                a["min_x"] < b["max_x"] < a["max_x"]
                and a["min_y"] < b["min_y"] < a["max_y"]):
            return True
        return False

    R = list(regions.items())
    neighbours = []
    for cur, a in enumerate(R[:-1]):
        for b in R[cur + 1:]:
            if intersect(a[1], b[1]):
                neighbours.append((a, b))
    return neighbours


def _merge_regions(r1, r2):
    """
    合并两个候选区域
    args:
        r1:候选区域1
        r2:候选区域2
    return:
        返回合并后的候选区域rt
    """
    new_size = r1["size"] + r2["size"]
    rt = {
        "min_x": min(r1["min_x"], r2["min_x"]),
        "min_y": min(r1["min_y"], r2["min_y"]),
        "max_x": max(r1["max_x"], r2["max_x"]),
        "max_y": max(r1["max_y"], r2["max_y"]),
        "size": new_size,
        "hist_c": (
                          r1["hist_c"] * r1["size"] + r2["hist_c"] * r2["size"]) / new_size,
        "hist_t": (
                          r1["hist_t"] * r1["size"] + r2["hist_t"] * r2["size"]) / new_size,
        "labels": r1["labels"] + r2["labels"]
    }
    return rt


def selective_search(
        im_orig, scale=1.0, sigma=0.8, min_size=50):
    """
    首先通过基于图的图像分割方法初始化原始区域,就是将图像分割成很多很多的小块
    然后我们使用贪心策略,计算每两个相邻的区域的相似度
    然后每次合并最相似的两块,直到最终只剩下一块完整的图片
    然后这其中每次产生的图像块包括合并的图像块我们都保存下来
    :param im_orig: ndarray 输入图像:(宽度,高度,3)或(宽度,高度)即灰度图或者rgb三通道彩色图
    :param scale: float 设置观察级别,规模越大意味着越来越小的部分
    :param sigma: float 高斯核的直径,用于在分割之前平滑图像
    :param min_size: int 最小组件大小,使用后处理强制执行
    :return: img : ndarray 包含区域信息的图像数据(宽度,高度,4)[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"
    # 载入图像,并获取图像的最小分割区域信息
    # region label is stored in the 4th value of each pixel [r,g,b,(region)]
    # 图片分割 把候选区域标签合并到最后一个通道上 height x width x 4  每一个像素的值为[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)   # dict类型,键值为候选区域的标签   值为候选区域的信息,包括候选区域的边框,以及区域的大小,颜色直方图,纹理特征直方图等信息
    # extract neighbouring information
    # list类型 每一个元素都是邻居候选区域对(ri,rj)  (即两两相交的候选区域)
    neighbours = _extract_neighbours(R)
    # calculate initial similarities
    S = {}
    # 计算每一个邻居候选区域对的相似度s(ri,rj)
    for (ai, ar), (bi, br) in neighbours:
        # S=S∪s(ri,rj)  ai表示候选区域ar的标签  比如当ai=1 bi=2 S[(1,2)就表示候选区域1和候选区域2的相似度
        S[(ai, bi)] = _calc_sim(ar, br, imsize)
    # hierarchal search 层次搜索 直至相似度集合为空
    while S != {}:
        # get highest similarity 获取相似度最高的两个候选区域  i,j表示候选区域标签
        i, j = sorted(S.items(), key=lambda i: i[1])[-1][0]  # 按照相似度排序
        # merge corresponding regions 合并相似度最高的两个邻居候选区域 rt = ri∪rj ,R = R∪rt
        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 S.items():  # k表示邻居候选区域对(i,j)  v表示候选区域(i,j)表示相似度
            if (i in k) or (j in k):
                key_to_delete.append(k)
        # remove old similarities of related regions 移除候选区域ri对应的所有相似度:S = S\s(ri,r*)  移除候选区域rj对应的所有相似度:S = S\s(r*,rj)
        for k in key_to_delete:
            del S[k]
        # calculate similarity set with the new region 计算新的候选区域rt对应的相似度集合St,S = S∪St
        for k in filter(lambda a: a != (i, j), key_to_delete):  # 过滤除了(i,j)之外的候选区域
            n = k[1] if k[0] in (i, j) else k[0]
            # 计算新的候选区域t与候选区域n之间的相似度
            S[(t, n)] = _calc_sim(R[t], R[n], imsize)
    # 获取每一个候选区域的的信息  边框、以及候选区域size,标签
    regions = []
    for k, r in 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']
        })
    # img:ndarray 基于图的图像分割得到的候选区域   regions:list Selective Search算法得到的候选区域
    return img, regions

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1983337.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBootWeb AOP

事务&AOP 1. 事务管理 1.1 事务回顾 在数据库阶段我们已学习过事务了&#xff0c;我们讲到&#xff1a; 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求。所以这组操作要…

kickstart自动安装脚本,pxe网络安装

目录 1 kickstart图形化生成脚本工具 1.1 安装apache 1.2 创建挂载镜像软链接 1.3 图形生成自动化脚本选项 1.4 修改生成的自动化脚本 1.5 将脚本放至网站根目录 2 安装系统 2.1 关闭DHCP自动分配 2.2 下载配置DHCP服务 2.3 重启DHCP服务 2.4 使用pxe方法安装系统&#xff08;网…

YOLOv5与YOLOv8 训练准备工作(不包含环境搭建)

前言&#xff1a;我发现除了安装环境需要耗费大量时间以外&#xff0c;对于训练前的准备工作也要琢磨一段时间&#xff0c;所以本篇主要讲一下训练前需要准备的工作&#xff08;主要是XML格式换为txt&#xff0c;以及划分数据集验证集&#xff0c;和训练参数的设置&#xff09;…

8–9月,​Sui Move智能合约工作坊将在台北+线上举行

你对区块链和去中心化应用感兴趣吗&#xff1f;想深入学习Sui Move编程语言吗&#xff1f; 从8月10日到9月28日&#xff0c;Sui Mover社区将在每周六下午13:00–17:00举办精彩的工作坊&#xff0c;为期两个月&#xff0c;带你从零基础入门到高级进阶&#xff0c;全面掌握Sui M…

Django配置模板引擎

【图书介绍】《Django 5企业级Web应用开发实战&#xff08;视频教学版&#xff09;》_django 5企业级web应用开发实战(视频教学版)-CSDN博客 《Django 5企业级Web应用开发实战&#xff08;视频教学版&#xff09;》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com) 本节主要介…

Linux之进程间通信(上)

目录 进程间通信的目的 进程通信的分类 进程通信之匿名管道 创建匿名管道 匿名管道的特点 匿名管道四种通信类型 在现实生活中&#xff0c;人们要进行合作&#xff0c;就必须进行交流&#xff0c;那么在进程之间&#xff0c;会存在交流的情景吗&#xff1f;答案是肯定的…

音频转换器在线哪个好?提升音频质量的转换工具

你是否曾梦想过将手机里的铃声变成自己的原创作品&#xff1f;或者&#xff0c;有没有想过将一段演讲录音转化为易于分享的MP3格式&#xff1f; 如果答案是肯定的&#xff0c;那么这款音频转换器mp3就是你寻找的答案。现在&#xff0c;让我们一起探索它的魅力吧&#xff01; 一…

基于MATLAB机器学习、深度学习实践技术

近年来&#xff0c;MATLAB在机器学习和深度学习领域的发展取得了显著成就。其强大的计算能力和灵活的编程环境使其成为科研人员和工程师的首选工具。在无人驾驶汽车、医学影像智能诊疗、ImageNet竞赛等热门领域&#xff0c;MATLAB提供了丰富的算法库和工具箱&#xff0c;极大地…

浏览器用户文件夹详解 - Preferences(十)

1.Preferences简介 1.1 什么是Preferences文件&#xff1f; Preferences文件是Chromium浏览器中用于存储用户个性化设置和配置的一个重要文件。每当用户在浏览器中更改设置或安装扩展程序时&#xff0c;这些信息都会被记录在Preferences文件中。通过这些记录&#xff0c;浏览…

海思ISP记录七:低照度图像调整

Hi3519av100imx585 记录下低照度图像调整的流程和思路 一、环境与配置 环境&#xff1a;暗房不开灯&#xff0c;只有零散漏光和电脑光亮gain与帧率&#xff1a;根据手册我设置的是Again&#xff1a;31282&#xff1b;Dgain&#xff1a;8192&#xff1b;ISP Dgain&#xff1a;…

B1.1 关于应用程序员模型-概述

快速链接: . 👉👉👉 ARMv8/ARMv9架构入门到精通-[目录] 👈👈👈 付费专栏-付费课程 【购买须知】个人博客笔记导读目录(全部) B1.1 关于应用程序员模型–概述 本章节包含了应用程序开发所需的程序员模型信息。 本章节中的信息不同于支持和服务于操作系统下应用程…

1.MySQL面试题之innodb如何解决幻读

1. 写在前面 在数据库系统中&#xff0c;幻读&#xff08;Phantom Read&#xff09;是指在一个事务中&#xff0c;两次读取同一范围的数据集时&#xff0c;由于其他事务的插入操作&#xff0c;导致第二次读取结果集发生变化的问题。InnoDB 作为 MySQL 的一个存储引擎&#xff…

PyTorch深度学习实战(2)——PyTorch快速入门

PyTorch的简洁设计使得它易于入门&#xff0c;在深入介绍PyTorch之前&#xff0c;本文先介绍一些PyTorch的基础知识&#xff0c;以便读者能够对PyTorch有一个大致的了解&#xff0c;并能够用PyTorch搭建一个简单的神经网络。 1 Tensor Tensor是PyTorch中最重要的数据结构&#…

docker、k8s部署 mysql group replication 和 ProxySQL 读写分离

MySQL Group Replication&#xff08;简称MGR&#xff09;是MySQL官方推出的一个高可用与高扩展的解决方案。MySQL组复制它提供了高可用、高扩展、高可靠的MySQL集群服务&#xff0c;这里部署的 mysql 版本 5.7.33&#xff0c;架构是一读一写。特别要注意一个关键点: 必须保证各…

sqli-labs-php7-master第11-16关

猜注入点 先来猜数字型 单引号字符型&#xff1a; 发现注入点找到了 猜测数据库有多少个字段&#xff1a; 1’ order by 4 # 密码随便输的。 这里没有使用--注释&#xff0c;因为没作用&#xff0c;可能是过滤掉了 继续猜。刚才没猜对 1 order by 2 # 没报错&#xff0c;猜…

如何将neo4j,4.x版本部署到服务器上

一. 简介 当我们使用neo4j构建知识图谱时&#xff0c;我们希望让别人能和我们共用neo4j进行知识图谱的构建&#xff0c;我们的方法之一就是将neo4j部署到我们的服务器上&#xff0c;然后将7474,7687端口暴露出来&#xff0c;这样就可以通过访问服务器公网IP的7474端口来操作我…

电脑硬盘坏了数据可以恢复吗?如何恢复硬盘数据?

电脑硬盘坏了数据可以恢复吗&#xff1f;对于这种问题&#xff0c;还需要具体问题具体分析的&#xff0c;一般是可以恢复。 硬盘损坏可以分为物理损坏和逻辑损坏两种情况&#xff1a; 1.逻辑损坏 这通常是由于软件问题&#xff0c;如文件系统错误、病毒攻击、误删除、格式化等…

CentOS Linux release 7.9.2009 中sudo命令未找到

先在 Windows 环境中下载 sudo 的安装包 选择适合自己 Centos 版本的安装包下载到本地&#xff1a;https://www.sudo.ws/releases/stable/ 然后把安装包拷贝的 Centos &#xff08;Linux系统&#xff09;中&#xff0c;cd 进入安装包所在的目录执行下面的命令&#xff1a; 格…

【Unity】线性代数基础:矩阵、矩阵乘法、转置矩阵、逆矩阵、正交矩阵等

文章目录 矩阵&#xff08;Matrix&#xff09;矩阵能干啥&#xff1f;矩阵基本运算矩阵加减法矩阵和标量的乘法矩阵和矩阵的乘法矩阵的转置矩阵相等 特殊的矩阵方块矩阵对称矩阵对角元素&#xff08;Diagonal Elements&#xff09;对角矩阵&#xff08;Diagonal Matrix&#xf…

sqli-labs-master初学者题目练习

Less-1 从源码可以看出id为注入点&#xff0c;且为单引号过滤 使用 闭合 --为注释 原本应该用--‘space’&#xff0c;但-与‘连在一起无法起到注释作用 order by为联合查询——同时查询两张表&#xff0c;但两张表列数必须相同 所有从以上两张图可以看出此表格有三列数据 爆…