2012-04-28 6 views
0

Я использую разницу кадров и opencv для обнаружения движения между кадрами (absdiff, threshold, erode и т. Д.).Обнаружить прямоугольник белых объектов на черном фоне с помощью opencv

Как получить координаты отдельных местоположений движений (прямоугольник: x, y, ширина, высота), в основном из белых капель?

+0

Сначала вы можете использовать 'cvFindContour'. Затем используйте 'cvBoundingRect', чтобы исправить его. –

ответ

2

Я делаю то же самое. Вот код, который у меня есть (некоторые вещи обрабатываются в разных классах, я просто собрал все вместе здесь). Первая часть - это то, что у вас уже есть, переход к части контуров.

/* This is the background subtraction you already have */ 
Mat tmp1; 
GaussianBlur(frame, tmp1, Size(5,5),0,0); //Blurring one image is sufficient to eliminate noise 
absdiff(tmp1, frameLast, tmp1); 
cvtColor(tmp1,tmp1,CV_RGB2GRAY); 
threshold(tmp1, tmp1, CV_THRESH_OTSU, 100, CV_THRESH_BINARY); 
/*cleaning up */ 
int erosion_type = MORPH_RECT; // MORPH_RECT, MORPH_CROSS, MORPH_ELLIPSE 
int erosion_size = 3; 
Mat erosion_element = getStructuringElement(erosion_type, Size(2*erosion_size + 1, 2*erosion_size+1), Point(erosion_size, erosion_size)); 

int dilation_type = MORPH_RECT; 
int dilation_size = 5; 
Mat dilation_element = getStructuringElement(dilation_type, Size(2*dilation_size + 1, 2*dilation_size+1), Point(dilation_size, dilation_size)); 

erode(tmp1,tmp1,erosion_element); 
dilate(tmp1,tmp1,dilation_element); 

/* Here I am getting the contours */ 
vector<vector<Point> > contours; 
findContours(tmp1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 
int minArea = 100, maxArea = 1000; //keep only contours of a certain size 
for (vector<vector<Point> >::iterator it=contours.end(); it!=contours.begin(); it--) { 
    if ((*it).size()<minArea || (*it).size()>maxArea) { 
     contours.erase(it); 
    } 
} 

drawContours(displayer, contours, a, Scalar(122,200,222),2); 

См here для получения более подробной информации (особенно вариантов, на которых контуры, чтобы найти, может помочь вам сузить то, что вы нашли. Я просто использовал CV_RETR_EXTERNAL).

Обратите внимание, что я сделал (перед) дисплей Mat, который является глубокой копией кадра (скопирован с frame.copyTo (displayer). Это потому, что если вы нарисуете материал непосредственно на фрейме, он будет перенесен на «frameLast» и выскочить со следующего абзаца. Конечно, вы могли бы избежать этого дополнительного изображения, просто скопировав рамку на frameLast перед рисованием (так рисуем все в конце), я делаю это, поэтому я могу легко рисовать из любого места в коде, упрощает работу, так как я пытаюсь много чего и хочу, чтобы время от времени мог видеть промежуточные шаги.

+0

Размер контура() не является областью. Это число точек в контуре. – kelin

0

В принципе, вы можете попробовать cvBlobsLib. В настоящее время это используется. Конечно, сначала это очень с трудом справляется с этим. Позже, когда вы его используете, он довольно прост в использовании. Он находит белые капли в изображении, наоборот. то вы можете использовать ограничительную рамку. оттуда вы можете получить местоположение точки.

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

  • Нет связанных вопросов^_^