cv2.dnn.NMSBoxes

cv2.dnn.NMSBoxes


opencv-python 中cv2.dnn.NMSBoxes接口说明很简单,如下

def NMSBoxes(bboxes, scores, score_threshold, nms_threshold, eta=None, top_k=None): # real signature unknown; restored from __doc__
    """
    NMSBoxes(bboxes, scores, score_threshold, nms_threshold[, eta[, top_k]]) -> indices
    .   @brief Performs non maximum suppression given boxes and corresponding scores.
    .   
    .        * @param bboxes a set of bounding boxes to apply NMS.
    .        * @param scores a set of corresponding confidences.
    .        * @param score_threshold a threshold used to filter boxes by score.
    .        * @param nms_threshold a threshold used in non maximum suppression.
    .        * @param indices the kept indices of bboxes after NMS.
    .        * @param eta a coefficient in adaptive threshold formula: \f$nms\_threshold_{i+1}=eta\cdot nms\_threshold_i\f$.
    .        * @param top_k if `>0`, keep at most @p top_k picked indices.
    """
    pass

其中,参数bboxes,没有太多有用的说明,我们目标检测算法不同,产生的bboxes的表示形式也有差异。所以需要弄清楚NMSBoxes函数的bboxes具体形式。既然Python接口中没有太多信息,我们查看C++的api说明。
翻阅Opencv-4.5.4的API文档,我们找到3个不同的API声明,如下的说明:
cv2.dnn.NMSBoxes_第1张图片
第三个与Python一致,我们查看其说明,与Python一致,说明是一样的,但遗憾的是其参说明没有提供比Python更多信息,
cv2.dnn.NMSBoxes_第2张图片
接下来,我们查看了其参数MatOfRect2d类型说明,一样无所获,没办法,去其C++源码,碰碰运气。
cv2.dnn.NMSBoxes_第3张图片

 /** @brief Performs non maximum suppression given boxes and corresponding scores.

     * @param bboxes a set of bounding boxes to apply NMS.
     * @param scores a set of corresponding confidences.
     * @param score_threshold a threshold used to filter boxes by score.
     * @param nms_threshold a threshold used in non maximum suppression.
     * @param indices the kept indices of bboxes after NMS.
     * @param eta a coefficient in adaptive threshold formula: \f$nms\_threshold_{i+1}=eta\cdot nms\_threshold_i\f$.
     * @param top_k if `>0`, keep at most @p top_k picked indices.
     */
    CV_EXPORTS void NMSBoxes(const std::vector<Rect>& bboxes, const std::vector<float>& scores,
                               const float score_threshold, const float nms_threshold,
                               CV_OUT std::vector<int>& indices,
                               const float eta = 1.f, const int top_k = 0);

    CV_EXPORTS_W void NMSBoxes(const std::vector<Rect2d>& bboxes, const std::vector<float>& scores,
                               const float score_threshold, const float nms_threshold,
                               CV_OUT std::vector<int>& indices,
                               const float eta = 1.f, const int top_k = 0);

NMSBoxes的C++源码声明如上,我们可以看到相似声明有3个,但我们显然不看其实现,看到其参数bboxes的有RectRect2d两种,查看其声明如下,其实就是Rect_在int、float、double的三种形态。

typedef Rect_<int> Rect2i;
typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;
typedef Rect2i Rect;

查看Rect_的定义,代码挺简单。

/** @brief Template class for 2D rectangles

described by the following parameters:
-   Coordinates of the top-left corner. This is a default interpretation of Rect_::x and Rect_::y
    in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner.
-   Rectangle width and height.

OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the
right and bottom boundaries are not. For example, the method Rect_::contains returns true if

\f[x  \leq pt.x < x+width,
      y  \leq pt.y < y+height\f]

Virtually every loop over an image ROI in OpenCV (where ROI is specified by Rect_\ ) is
implemented as:
@code
    for(int y = roi.y; y < roi.y + roi.height; y++)
        for(int x = roi.x; x < roi.x + roi.width; x++)
        {
            // ...
        }
@endcode
In addition to the class members, the following operations on rectangles are implemented:
-   \f$\texttt{rect} = \texttt{rect} \pm \texttt{point}\f$ (shifting a rectangle by a certain offset)
-   \f$\texttt{rect} = \texttt{rect} \pm \texttt{size}\f$ (expanding or shrinking a rectangle by a
    certain amount)
-   rect += point, rect -= point, rect += size, rect -= size (augmenting operations)
-   rect = rect1 & rect2 (rectangle intersection)
-   rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 )
-   rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
-   rect == rect1, rect != rect1 (rectangle comparison)

This is an example how the partial ordering on rectangles can be established (rect1 \f$\subseteq\f$
rect2):
@code
    template inline bool
    operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2)
    {
        return (r1 & r2) == r1;
    }
@endcode
For your convenience, the Rect_\<\> alias is available: cv::Rect
*/
template<typename _Tp> class Rect_
{
public:
    typedef _Tp value_type;

    //! default constructor
    Rect_();
    Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
#if OPENCV_ABI_COMPATIBILITY < 500
    Rect_(const Rect_& r) = default;
    Rect_(Rect_&& r) CV_NOEXCEPT = default;
#endif
    Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
    Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);

#if OPENCV_ABI_COMPATIBILITY < 500
    Rect_& operator = (const Rect_& r) = default;
    Rect_& operator = (Rect_&& r) CV_NOEXCEPT = default;
#endif
    //! the top-left corner
    Point_<_Tp> tl() const;
    //! the bottom-right corner
    Point_<_Tp> br() const;

    //! size (width, height) of the rectangle
    Size_<_Tp> size() const;
    //! area (width*height) of the rectangle
    _Tp area() const;
    //! true if empty
    bool empty() const;

    //! conversion to another data type
    template<typename _Tp2> operator Rect_<_Tp2>() const;

    //! checks whether the rectangle contains the point
    bool contains(const Point_<_Tp>& pt) const;

    _Tp x; //!< x coordinate of the top-left corner
    _Tp y; //!< y coordinate of the top-left corner
    _Tp width; //!< width of the rectangle
    _Tp height; //!< height of the rectangle
};

能用到的构造函数就是

Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);

其参数说明,可以参考类变量注释:

    _Tp x; //!< x coordinate of the top-left corner
    _Tp y; //!< y coordinate of the top-left corner
    _Tp width; //!< width of the rectangle
    _Tp height; //!< height of the rectangle

所以cv2.dnn.NMSBoxes的bboxes框应该是左上角坐标(x,y)和 w,h, 那么针对不同模型的,要具体情况转化一下,才能应用该函数。

你可能感兴趣的:(opencv,dnn,计算机视觉,python)