前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >目标检测之选择性搜索算法实现(符动图演示)

目标检测之选择性搜索算法实现(符动图演示)

作者头像
机器视觉CV
发布2019-12-10 16:53:11
8190
发布2019-12-10 16:53:11
举报
文章被收录于专栏:机器视觉CV机器视觉CV
本文建议阅读时间 8 min

本文简单对目标检测中的选择性搜索进行说明,并用 OpenCV 对其进行实现,且看:

定义

选择性搜索是在对象检测中使用的区域提议算法。它的设计速度很快,召回率很高。它基于基于颜色,纹理,大小和形状兼容性的相似区域的分层分组计算。

操作步骤

  1. 首先使用 Felzenszwalb 和 Huttenlocher 基于图像的分割方法
  2. 对分割的图像进行超像素的合并,合并彼此相似的相邻区域 ,合并的规则包括颜色相似度、纹理相似度、尺寸相似度、形状相似性等 自下而上的方法创建了从较小细分到较大细分的区域建议 ,如下图所示

合并规则

  • 颜色相似度

计算图像每个通道的 25 个 bins 的颜色直方图,并将所有通道的直方图连接起来,得到 25×3 = 75 维的颜色描述符(归一化)。

其中

代表两块区域,

代表第 i 块区域直方图中第 k 个 bins 的颜色描述符,以上公式表示

两块区域的 n=75 维颜色描述符完全一致的话(就是两块区域的 75 维直方图一对一完全相同)那么说明这两块区域的颜色完全相同,可以进行合并

  • 纹理相似度

通过为每个通道在 8 个方向上提取高斯导数来计算纹理特征。对于每个方向和每个颜色通道,都将计算 10 bin 直方图,从而生成 10x8x3 = 240 维特征描述符。

以上的公式与颜色相似度的计算公式指代的意义差不多,都是计算每块区域的纹理特征,再比较不同区域的纹理相似度

  • 尺寸相似度

大小相似性鼓励较小的区域尽早合并。它可以确保在图像的所有部分形成所有尺度的区域建议。如果不考虑这种相似性度量,则单个区域将使所有较小的相邻区域一一吞并,因此仅在该位置会生成多个尺度的区域建议。大小相似度定义为

上面的公式表示,两个区域越小,其相似度越大,越接近 1。size (im) 计算的是图片的像素个数

  • 形状相容性

形状兼容性可衡量两个区域相互配合的程度,如果匹配则进行合并,如果它们接触都没有,则不合并,BB_ij 代表 r_i 和 r_j 的外接矩形

  • 最终相似度

最终相似度就是在上面四个相似度的基础上添加一个权重来计算最终相似度,公式如下:

代码实现

先上效果:

在 OpenCV 中,提供了一个选择性搜索的接口供我们使用,这个模块是在 OpenCV 扩展模块包 opencv-contrib-python 里面

首先需要进行安装 pip install opencv-contrib-python

所有代码都进行了注释,这里就不在赘述

#!/usr/bin/env python
'''
安装依赖
!pip install opencv-python
!pip install opencv-contrib-python


Usage:
    ./ssearch.py input_image (f|q)
    f=fast, q=quality
Use "l" to display less rects, 'm' to display more rects, "q" to quit.
'''

import sys
import cv2
if __name__ == '__main__':
    # If image path and f/q is not passed as command
    # line arguments, quit and display help message

    # speed-up using multithreads
    cv2.setUseOptimized(True);
    cv2.setNumThreads(4)  # 设置线程数

    # read image
    path = "F:/jupyter/Dive-into-DL-PyTorch/docs/img/cat1.jpg"
    im = cv2.imread(path)

    # resize image 重置大小
    newHeight = 2000
    newWidth = int(im.shape[1]*200/im.shape[0])
#     im = cv2.resize(im, (newWidth, newHeight))    

    # create Selective Search Segmentation Object using default parameters
    # 使用默认参数创建一个选择性搜索的分割对象
    ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()

    # set input image on which we will run segmentation    
    ss.setBaseImage(im)


    model = "f"   # 快速模式 f 还是 高召回率模式 q
    # 三种模式,参考
    # https://docs.opencv.org/3.4/d6/d6d/classcv_1_1ximgproc_1_1segmentation_1_1SelectiveSearchSegmentation.html

    # Switch to fast but low recall Selective Search method
    # 快速模式,但是意味着低召回率
    if (model == 'f'):
        ss.switchToSelectiveSearchFast()

    # Switch to high recall but slow Selective Search method
    # 高召回率模式,但是速度较慢
    elif (model == 'q'):
        ss.switchToSelectiveSearchQuality()
    elif (model == "ToString"):
        ss.switchToSingleStrategy()
    # if argument is neither f nor q print help message
    else:
        print("plase set model!")

    # run selective search segmentation on input image
    # 运行选择性搜索算法,返回他们的可能边框
    rects = ss.process()
    print('Total Number of Region Proposals: {}'.format(len(rects)))

    # number of region proposals to show
    numShowRects = 10
    # increment to increase/decrease total number of reason proposals to be shown
    increment = 20

    while True:
        # create a copy of original image
        # 复制一份图片
        imOut = im.copy()

        # itereate over all the region proposals
        for i, rect in enumerate(rects):
            # draw rectangle for region proposal till numShowRects
            # 绘制边框
            if (i < numShowRects):
                x, y, w, h = rect 
                cv2.rectangle(imOut, (x, y), (x+w, y+h), (0, 255, 0), 1, cv2.LINE_AA)
            else:
                break

        # show output
        cv2.imshow("Output", imOut)
        cv2.imwrite("Output.jpg", imOut)

        # record key press 
        k = cv2.waitKey(0) & 0xFF
        # m is pressed  m  键增加要显示的矩形框数
        if k == 109:
            # increase total number of rectangles to show by increment
            numShowRects += increment

        # l is pressed  l 键减少要显示的矩形框数
        elif k == 108 and numShowRects > increment:
            # decrease total number of rectangles to show by increment
            numShowRects -= increment

        # q is pressed  q 键退出
        elif k == 113:
            break

    # close image show window
    cv2.destroyAllWindows() 

参考:

  • https://www.learnopencv.com/selective-search-for-object-detection-cpp-python/
  • http://cs.brown.edu/~pff/segment/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器视觉CV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本文简单对目标检测中的选择性搜索进行说明,并用 OpenCV 对其进行实现,且看:
  • 定义
  • 操作步骤
  • 合并规则
  • 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档