2015-08-25 4 views
0

Я работаю над обнаружением объекта в видео. У меня есть 5-6 объектов, приблизительно в каждом кадре, и я обнаруживаю угловые точки каждого объекта. Теперь, как я могу определить внешнюю границу каждого объекта, используя только угловые точки.Чтобы нарисовать прямоугольник вокруг объекта

+3

Пожалуйста, добавьте изображение, содержащее объекты, и код, который вы использовали до сих пор – Miki

+0

Откуда эти точки? Они уже сгруппированы по объекту? Если да, просто используйте cv :: boundingRect. Что касается разделения двух близлежащих объектов, вы не собираетесь это делать ... Что, если это длинный грузовик вместо двух автомобилей? – Miki

+0

@Miki это угловые точки. нет, они не сгруппированы. Я хочу сгруппировать их в конкретный объект и нарисовать его окружение. – Arjun

ответ

0

вы можете перемещать каждую угловую точку и находить значения max и min.

Пример:

//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}

Порядок, в котором вы указываете баллы, не имеет значения.

Надеюсь, мой ответ вам поможет.

+2

Вы когда-нибудь слышали о OpenCV? Хотя концепция в вашем ответе может быть правильной (трудно сказать из вопроса, на самом деле), вы код, как изобретать колесо – Miki

+0

Я думаю, что эти цветные точки являются вашими угловыми точками, не так ли?Поэтому вам нужно использовать их только в качестве входных данных для функции – Philinator

+0

@Philinator Спасибо. Да, это угловые точки. Как я определяю, что эти точки принадлежат одному объекту, так что я могу дать эти точки в качестве входных данных для этой функции. – Arjun

Смежные вопросы