简体   繁体   中英

How do i actually set optical flow on half of the image captured?

I already had an optical flow code implemented using C++ in OpenCV. However, i would like to detect optical flow in half of the image frame. Which part should i edit? is it from this function below?

cvCalcOpticalFlowPyrLK(
  frame1_1C, frame2_1C, 
  pyramid1, pyramid2, 
  frame1_features, 
  frame2_features, 
  number_of_features, 
  optical_flow_window, 
  5, 
  optical_flow_found_feature, 
  optical_flow_feature_error, 
  optical_flow_termination_criteria, 
  0 );

No. There are no changes necessary in the function itself. All you need to do is pass only the part of image on which you want to calculate optical flow to the function.

You can define the range of the image that you want to carry out the optical flow calculations on. using

wanted_image=image(Range(x1,y1), Range(x2,y2))

The following is a working code based on the lkdemo.cpp in the samples folder. THe only worthwhile change is

gray = gray(Range(1,480), Range(1,320)); //Gives the left half of the image

which defines the region of interest.

#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <ctype.h>

using namespace cv;
using namespace std;

static void help()
{
    cout << "*** Using OpenCV version " << CV_VERSION <<" ***"<< endl;
    cout << "\n\nUsage: \n"
            "\tESC - quit the program\n"
            "\tr - auto-initialize tracking\n"
            "\tc - delete all the points\n"
            "\tn - switch the \"night\" mode on/off\n"<< endl;
}

int main( int argc, char** argv )
{
    help();
     //Termination of the algo after 20 iterations or accuracy going under 0.03 
    TermCriteria termcrit(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 20, 0.3);
    Size subPixWinSize(10,10), winSize(31,31);
    const int MAX_COUNT = 500;
    bool needToInit = false;
    bool nightMode = false;
    //Video capture is from the default device i.e. the webcam
    VideoCapture cap(0);
    if( !cap.isOpened() )
    {
        cout << "Could not initialize capturing...\n";
        return 0;
    }

    namedWindow( "Half screen Optical flow Demo!", 1 );
    Mat gray, prevGray, image;
    vector<Point2f> points[2];

    for(;;)
    {
        Mat frame;

        //Output from the Videocapture is piped to 'frame'
        cap >> frame;
        if( frame.empty() )
            break;

        frame.copyTo(image);
        cvtColor(image, gray, COLOR_BGR2GRAY);

        // Night mode not disabled
        if( nightMode )
            image = Scalar::all(0);
        gray = gray(Range(1,480), Range(1,320));
        if( needToInit || points[0].size()<=5)
        {                  
            goodFeaturesToTrack(gray, points[1], MAX_COUNT, 0.01, 10, Mat(), 3, 0, 0.4);
            cornerSubPix(gray, points[1], subPixWinSize, Size(-1,-1), termcrit);

        }
        else if( !points[0].empty() )
        {
            vector<uchar> status;
            vector<float> err;
            if(prevGray.empty())
                gray.copyTo(prevGray);
            calcOpticalFlowPyrLK(prevGray, gray, points[0], points[1], status, err, winSize, 3, termcrit, 0, 0.001);
            size_t i, k;

            for( i = k = 0; i < points[1].size(); i++ )
            {
                if( !status[i] )
                    continue;

                points[1][k++] = points[1][i];  
                circle(image, points[1][i], 3, Scalar(0,255,0), -1, 8);
            }
            points[1].resize(k);
        }      
        needToInit = false;
        imshow("Half screen Optical flow Demo!", image);

        char c = (char)waitKey(10);
        if( c == 27 )
            break;
        switch( c )
        {
        case 'r':
            needToInit = true;
            break;
        case 'c':
            points[0].clear();
            points[1].clear();
            break;
        case 'n':
            nightMode = !nightMode;
            break;
        }
        std::swap(points[1], points[0]);
        cv::swap(prevGray, gray);
    }
    cap.release();
    return 0;
}

if you want to detect optical flow only in the half of the image, then you can simply give halves of the images (frame1_1C, frame2_1C) as parameters. For example, following code initializes a matrix belonging to the left half of frame1_1C:

cv::Mat frame1_1C_half(frame1_1C, cv::Range(0, frame1_1C.rows), cv::Range(0, frame1_1C.cols/2));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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