0

Я использую C++, библиотеку OpenCV и в своем программном обеспечении, я оценил оптический поток в видео. Теперь я хочу сгруппировать некоторые движущиеся объекты, например. движущихся автомобилей. Я использовал алгоритм плотного оптического потока (Farneback).Сегментация изображения на основе оптического потока

Мои первые мысли до сих пор - использовать алгоритм «k означает» для кластеризации.

Я подумал, используя результаты оптического потока Farneback вычислить смещение кадров в каждом направлении следующим образом:

Е.Г. :

Пусть Dx - смещение в направлении x (положительное или отрицательное) и Dy смещение в направлении y (положительное или отрицательное).

Затем я передаю массив [Dx, Dy] в качестве входа в k с k = 2 кластерами. Надеюсь, это даст грубую предпосылку/переднюю часть.

Однако я столкнулся с проблемами при вычислении смещения, потому что выход calcOpticalFlowFarneback представляет собой поток InputOutputArray. Должен ли я обращаться к этому массиву с помощью такой функции, как например? :

findDisplacements(const Mat& flow, int step) { 
const Point2f& Dx,Dy; 
const Point2f& fxy = flow.at<Point2f>(y, x); 
Dx=Point(cvRound(x+fxy.x))-Point(x,y); 
Dy=Point(cvRound(y+fxy.y))-Point(y,x); 
} 
+0

Какие вещи вы уже пробовали? – VKatz

+0

Я уже использовал kmeans, который работает, я думаю, и возвращает массив bestLabels. Однако мне не удалось показать результат как изображение. Я также работаю над другим кодом, использующим фоновое выражение, которое также работает. Должен ли я объединить их? Или использовать, например, базовую субтракцию, а k означает позже? –

+0

Какой плотный алгоритм оптического потока вы использовали? – ChronoTrigger

ответ

0

Небольшой пример, в котором векторы движения используются в качестве признака для кластера:

cv::Mat img0 = cv::imread("test0.png"); // Image at time t-1 
cv::Mat img1 = cv::imread("test1.png"); // Image at time t 
cv::Mat flow; 
//estimate Optical Flow 
cv::calcOpticalFlowFarneback(img0, img1, flow, 0.5, 3, 21, 20, 5, 1.1); 
std::vector<cv::Point2f> samples(flow.rows * flow.cols); 
// arange sample vector 
int n = 0; 
for(int r = 0; r < flow.rows; r++) { 
    for(int c = 0; c < flow.cols; c++){ 
    samples[n++] = flow.at<cv::Point2f>(r,c); 
}} 
cv::kmeans(samples, ... 
0

Вы можете использовать историю движения.

updateMotionHistory(silh, mhi, timestamp, MHI_DURATION); 
calcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3); 
segmentMotion(mhi, segmask, regions, timestamp, MAX_TIME_DELTA);