I am trying to use the CalcOpticalFlowBM function but I don't understand hot it works. I want to find a motion vector for every blocks but I don't understand that the CalcOpticalFlowBM yields velX and velY. I wrote below code .

/* Create an object that decodes the input video stream. */
	CvCapture * input_video = cvCaptureFromFile(
		"optical_flow_input.avi");
	if (input_video == NULL)
	{
		fprintf(stderr, "Error: Can't open video.\n");
		return -1;
	}

    CvSize frame_size;
	frame_size.height =
		(int) cvGetCaptureProperty
( input_video, CV_CAP_PROP_FRAME_HEIGHT );
	frame_size.width =
		(int) cvGetCaptureProperty
( input_video, CV_CAP_PROP_FRAME_WIDTH );

    	/* Determine the number of frames in the AVI. */
	long number_of_frames;
	/* Go to the end of the AVI (ie: the fraction is "1") */
	cvSetCaptureProperty 
(input_video, CV_CAP_PROP_POS_AVI_RATIO, 1.);
	/* Now that we're at the end, read the AVI position in frames */
	number_of_frames = ( int ) 
cvGetCaptureProperty (input_video, CV_CAP_PROP_POS_FRAMES);
	/* Return to the beginning */
	cvSetCaptureProperty 
(input_video, CV_CAP_PROP_POS_FRAMES, 0.);

    IplImage * source[ 2 ], * image[ 2 ];
    source[ 0 ] = cvCreateImage (frame_size, IPL_DEPTH_8U, 1);
    source[ 1 ] = cvCreateImage (frame_size, IPL_DEPTH_8U, 1);
    image[ 0 ] = cvCreateImage(frame_size, IPL_DEPTH_8U, 3);
    image[ 1 ] = cvCreateImage(frame_size, IPL_DEPTH_8U, 3);

    int current_frame = 300;
    cvSetCaptureProperty
( input_video, CV_CAP_PROP_POS_FRAMES, current_frame);

    IplImage * frame = cvQueryFrame( input_video );
    if (frame == NULL) {
        /* Why did we get a NULL frame?  We shouldn't be at the end. */
        fprintf(stderr, 
"Error: Hmm. The end came sooner than we thought.\n");
        return -1;
    }

    cvConvertImage(frame, image[ 0 ], CV_CVTIMG_FLIP);
    ++current_frame;
    cvSetCaptureProperty
( input_video, CV_CAP_PROP_POS_FRAMES, current_frame);

    frame = cvQueryFrame( input_video );
	if (frame == NULL) {
        fprintf(stderr,
 "Error: Hmm. The end came sooner than we thought.\n");
		return -1;
    }

    cvConvertImage(frame, image[ 1 ], CV_CVTIMG_FLIP);
//    cvNamedWindow ("frm", CV_WINDOW_AUTOSIZE);
//    cvShowImage ("frm", image[ 0 ]);

    cvCvtColor (image[ 0 ], source[ 0 ], CV_BGR2GRAY);
    cvCvtColor (image[ 1 ], source[ 1 ], CV_BGR2GRAY);

    cvNamedWindow("Pic1", CV_WINDOW_AUTOSIZE);
    cvShowImage("Pic1", source[ 0 ]);

    cvNamedWindow("Pic2", CV_WINDOW_AUTOSIZE);
    cvShowImage("Pic2", source[ 1 ]);

    CvSize size;
    size = cvGetSize( source[ 0 ] );

    size.height /= 16;
    size.width  /= 16;

    IplImage * velocityX = cvCreateImage(size, IPL_DEPTH_32F, 1),
             * velocityY = cvCreateImage(size, IPL_DEPTH_32F, 1);

    cvCalcOpticalFlowBM (source[ 0 ], source[ 1 ],
                      cvSize(16, 16), cvSize(1, 1), cvSize(3, 2), 0, 
                      velocityX, velocityY);


    cvNamedWindow ("Horizontal", CV_WINDOW_AUTOSIZE);
    cvShowImage ("Horizontal", velocityX);

    cout << velocityX->height;
    cout << endl << velocityX->width;

    cvNamedWindow ("Vertical", CV_WINDOW_AUTOSIZE);
    cvShowImage ("Vertical", velocityY);

    cvWaitKey( 0 );

    cvDestroyWindow( "Pic1" );
    cvDestroyWindow( "Pic2" );
    cvDestroyWindow( "Horizontal" );
    cvDestroyWindow( "Vertical" );

    cvReleaseImage( &source[ 1 ] );
    cvReleaseImage( &source[ 0 ] );
    cvReleaseImage( &image[ 1 ] );
    cvReleaseImage( &image[ 0 ] );
    cvReleaseImage( &velocityY );
    cvReleaseImage( &velocityX );

Recommended Answers

All 7 Replies

I googled the function name and came up with this description:

The function cvCalcOpticalFlowBM calculates optical flow for overlapped blocks blockSize.width×blockSize.height pixels each, thus the velocity fields are smaller than the original images. For every block in imgA the functions tries to find a similar block in imgB in some neighborhood of the original block or shifted by (velx(x0,y0),vely(x0,y0)) block as has been calculated by previous function call (if usePrevious=1)

So it would seem that the function is trying to measure motion between two pictures. It looks for matching blocks in each picture and returns the speed at which the block(s) were moving.

It is returning how far in x and how far in y the block moved. If you need a vector for the motion, you will probably have to calculate it from the velX and velY.

Thank you for your answer but actually I want to learn how I can calculate the blocks move from the velX and velY. This is my problem. Thank you a lot...

That sounds like basic Geometry or Physics, but let's play pretend.

Pretend you're writing a function to calculate what you want. Write a prototype for the function. (What arguments will it take, what will it return?)

I have no idea. Do you have? I really need some help...

I was trying to get you to explain what it was you thought you needed. If you don't know what you need, how will you know when you find it.

I need a number which shows us to how many pixels a block move in x and y coordinates? But I can't fetch this numbers from velX and velY

Hi stonerain..
I am using CalcOpticalFlowBM function for calculating motion vectors too.. But I am not quite sure how it can be used to obtain motion vectors. Please reply if you have already figured it out!
Thanks in anticipation
:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.