C# Emgu : Use of DISOpticalFlow

2019-06-11 15:16发布

问题:

Good day everyone,

I'm trying to build a real time frame interpolation programm for videos. Because I have always worked with C#, I choose to use OpenCV with Emgu 3.2.0 (lastest version avaible).

So, here is it :

First, I have 2 images named frame1 and frame2, wich are obviously two frames from my video.

Next I build my DISOpticalFlow object as following

Now I must use it to get the translation vector between those 2 frames.

So I build a Gray Image named flow and I use DISOpticalFlow's calc method.

Aaaaand ... Nothing. Whatever I try, flow is always empty (see this screen : http://imgur.com/ozN0XgN)

What am I missing or doing wrong ?

Thanks everyone for reading and have a great day !

CODE :

//My items
Image<Bgr, Byte> frame1 = new Image<Bgr, Byte>(1280, 720);
Image<Bgr, Byte> frame2 = new Image<Bgr, Byte>(1280, 720);
DISOpticalFlow opticalFlowAlgorithm = new DISOpticalFlow(DISOpticalFlow.Preset.Medium);
Image<Gray, Byte> flow= new Image<Gray, Byte>(1280, 720);


//Get my frame from my server
//Note : this is working without any problem, if I display those frames with CvInvoke.Imshow, everything is good
server.waitFrame.WaitOne();
frame1.Bytes = server.frame1;
server.waitFrame.WaitOne();
frame1.Bytes = server.frame1;

//Now I get my optical flow :
opticalFlowAlgorithm.Calc(frame1.Convert<Gray, byte>(), frame2.Convert<Gray, byte>(), flow);

回答1:

I'm not an EmguCV expert, but if i remember correctly Image can only store integer values. If you define "flow" as an Image, you will lose information because DISOpticalFlow should return a float matrix.

In opencv c++, i declare my flow matrix such as

 Mat_<Point2f> flow;

Then convert it to an image by mapping the magnitude and the orientation of the flow to the color space.



回答2:

Any optical flow field is a continuous (i.e. float or double) 2 channel (X and Y pixel motion) map. To display it you have to map it to a visual range. The easiest would be displaying the motion magnitude by computing max(255,Channel_0*Channel_0 + Channel_1*Channel_1), rounding/converting it to back to integer. Additionally, the passed data type likely has to be a float map as well.

Disclaimer: I have never used Emgu, nor the OpenCV version of DISFlow. But I am the author of the original paper, and my code (https://github.com/tikroeger/OF_DIS) would have to be used in this way.