简体   繁体   English

基于光流的图像分割

[英]Image segmentation based on optical flow

I am using c++,OpenCV library and in my software, I have estimated the optical flow in a video. 我正在使用c ++,OpenCV库,并且在我的软件中,我估计了视频中的光流。 Now, I want to group some moving objects, eg moving cars. 现在,我想对一些移动物体进行分组,例如移动汽车。 I have used a dense optical flow algorithm (Farneback). 我使用了密集的光流算法(Farneback)。

My first thoughts so far are to use "k means" algorithm to do the clustering. 到目前为止,我的第一个想法是使用“ k均值”算法进行聚类。

I have thought of using the results of the Farneback optical flow to compute the displacement of the frames in each direction as following : 我已经考虑过使用Farneback光流的结果来计算框架在每个方向上的位移,如下所示:

Eg : 例如:

Let Dx be the displacement in x direction( either positive or negative) and Dy the displacement in y direction(either positive or negative) . 设Dx为x方向的位移(正或负),Dy为y方向的位移(正或负)。

Then i pass the array [Dx,Dy] as an input to k means with k=2 clusters. 然后我将数组[Dx,Dy]作为输入传递给k = 2个簇的k均值。 I hope this will give a rough background / foreground substraction . 我希望这会给背景/前景带来一个粗略的扣除。

However i am facing problems in computing the displacemet because the output of calcOpticalFlowFarneback is InputOutputArray flow . 但是,由于calcOpticalFlowFarneback的输出是InputOutputArray流,因此在计算置换器时遇到了问题。 Should I access this array using a function like that for example ? 我是否应该使用类似的函数来访问此数组? :

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);
}

A small example where the motion vectors are used as feature to cluster: 一个小示例,其中将运动矢量用作聚类的特征:

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, ...

You can use the history of motion. 您可以使用运动历史记录。

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM