在对象周围绘制一个矩形

时间:2015-08-25 12:01:41

标签: c++ opencv image-processing computer-vision

我正在研究视频中的对象检测。我在每帧中有大约5到6个物体,我检测每个物体的角点。现在我怎么能只使用角点来确定每个物体的外部边界。

1 个答案:

答案 0 :(得分:0)

你可以遍历每个角点并找到最大值和最小值。

示例:

    //includes
#include<vector>
#include <math.h>
using namespace std;

//defines
#define INFINITY ((1e+300)*(1e+300))
#define MIN(x,y) ((x)<(y)?(x):(y))
#define MAX(x,y) ((x)>(y)?(x):(y))

struct SBoundary {
    float top, bottom, left, right;
};

struct SPoint {
    SPoint(float _x,float _y):x(_x),y(_y) {}
    float x, y;
};

float PointDistance(SPoint& p1, SPoint& p2) {
    return sqrt((p2.x - p1.x)*(p2.x - p1.x) + (p2.y - p1.y)*(p2.y - p1.y));
}
const float maxDistance = 2.0/*find an appropiate minimum distance between points*/;

vector<vector<SPoint>> seperateObjects(vector<SPoint> Points) {
    vector<vector<SPoint>> Objects;

    vector<SPoint>::iterator it = Points.begin();
    while (Points.size() != 0) {
        SPoint buffer = Points[0];
        it = Points.erase(Points.begin());//erase first point from list - function return iterator for next element

        vector<SPoint> newObject;
        newObject.push_back(buffer);

        for (unsigned int i = 0; i < newObject.size(); i++) {
           vector<SPoint>::iterator it3 = Points.begin();
           while (it3 != Points.end()) {
                float _distance = PointDistance(newObject[i], *it3);
                 if (_distance <= maxDistance) {//point belongs to Object
                    newObject.push_back(*it3);
                    it3 = Points.erase(it3); //process this point only once - function return iterator for next element
                }
                else {
                    it3++;
                }
            }
        }

        Objects.push_back(newObject);
    }

    return Objects;

}

SBoundary findBoundaries(vector<SPoint> vertices) {

    SBoundary Boundary;

    Boundary.top = INFINITY;
    Boundary.bottom = -INFINITY;
    Boundary.left = INFINITY;
    Boundary.right = -INFINITY;

    for (unsigned int i = 0; i < vertices.size();i++) {
        Boundary.top = MIN(Boundary.top, vertices[i].y);
        Boundary.bottom = MAX(Boundary.bottom, vertices[i].y);

        Boundary.left = MIN(Boundary.left, vertices[i].x);
        Boundary.right = MAX(Boundary.right, vertices[i].x);
    }

    return Boundary;
}

您可以使用以下这些功能:

vector<SBoundary> findAllBoundaries(vector<SPoint> Points) {

    vector<SBoundary> Boundaries;
    vector<vector<SPoint>> Objects = seperateObjects(Points);

    for (unsigned int i = 0;i < Objects.size();i++) {
        Boundaries.push_back(findBoundaries(Objects[i]));
    }
    return Boundaries;
}

现在你所要做的就是调用这个函数并传递角点的矢量作为参数,你将返回你的边界框。

maxDistance常量应设置为一个值,该值表示属于同一个对象且彼此相邻的两个点之间的最大距离。

示例点集(适用于maxDistance = 2.0):

vector<SPoint> points;

points.push_back(SPoint(1.0, 1.0));
points.push_back(SPoint(2.0, 2.0));
points.push_back(SPoint(3.0, 3.0));
points.push_back(SPoint(4.0, 2.0));
points.push_back(SPoint(1.0, 3.0));
points.push_back(SPoint(8.0, 5.0));
points.push_back(SPoint(10.0, 6.0));
points.push_back(SPoint(9.0, 6.0));
points.push_back(SPoint(8.0, 7.0));

vector<SBoundary> boundaries = findAllBoundaries(points);

这组点将导致两个对象,并且该函数为它们返回正确的边界框。

物件:

  1. {1,1},{2,2},{1,3},{4,2},{3,3}

  2. {8,5},{10,5},{9,6},{8,7}

  3. 您提供积分的顺序无关紧要。

    我希望我的回答会对你有帮助。