• opencv入门笔记之四 读写视频 捕捉移动点


     

     捕捉移动点时,  我们可以使用一种叫做 光学流动(optical flow) 的算法,  在关键点的周围,  所有点的流动导数都是相同的,  从而我门可以判断出关键点( feature points)

     下面是代码:

    classCameraCaliberator

    {

    vector<vector<Point3f>> objectPoints;

    // the real points

    vector<vector<Point2f>> imagePoints;

    // points found inimage

    Mat cameraMatrix;

    Mat distCoeffs;

    int flag;

    Mat map1, map2;

    bool mustInitUndistort;

    public:

    CameraCaliberator() :flag(0), mustInitUndistort(true)

    {

    };

    int addChessboardPoints(

    const vector<string>& filelist, Size &boardSize){

    vector<Point2f> imageCorners;

    vector<Point3f> objectCorners;

    for (int i = 0; i < boardSize.height;i++)

    {

    for (int j = 0; j < boardSize.width;j++)

    {

    objectCorners.push_back(Point3f(i, j,0.0f));        

    }

    }

    Mat image;

    int successes = 0;

    for (int i = 0; i < filelist.size();i++)

    {

    image = imread(filelist[i], 0);

    bool found = findChessboardCorners(image, boardSize, imageCorners);

    cornerSubPix(image, imageCorners, Size(5, 5), Size(-1, -1),

    TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 30, 0.1));

    //used to define when to stop

    if (imageCorners.size() == boardSize.area())

    {

    addPoints(imageCorners, objectCorners);

    successes++;

    }

    }

    return successes;

    }

    double calibrate(Size &imageSize){

    mustInitUndistort = true;

    vector<Mat> rvecs, tvecs;

    return        calibrateCamera(objectPoints,

    imagePoints,

    imageSize,

    cameraMatrix,

    distCoeffs,

    rvecs,

    tvecs,

    flag);

    }

    Mat remap(const        Mat&image){

    Mat undistorted;

    if (mustInitUndistort){

    initUndistortRectifyMap(cameraMatrix,

    distCoeffs,

    Mat(), Mat(),

    image.size(),

    CV_32FC1,

    map1, map2);

    }

    mustInitUndistort = false;

    cv::remap(image, undistorted, map1, map2, INTER_LINEAR);

    return undistorted;

    };

    //        // Set the calibration options

    //        // 8radialCoeffEnabled shouldbe true if 8 radial coefficients are required (5 is default)

    //        // tangentialParamEnabledshould be true if tangeantial distortion is present

    //        voidCameraCaliberator::setCalibrationFlag(bool radial8CoeffEnabled, booltangentialParamEnabled) {

    //

    //                //Set the flag used in cv::calibrateCamera()

    //                flag= 0;

    //                if(!tangentialParamEnabled) flag += CV_CALIB_ZERO_TANGENT_DIST;

    //                if(radial8CoeffEnabled) flag += CV_CALIB_RATIONAL_MODEL;

    //        }

    private:

    void addPoints(vector<Point2f>& imageCorners,vector<Point3f>& objectCorners){

    imagePoints.push_back(imageCorners);

    objectPoints.push_back(objectCorners);

    }

    };

    void m(){

    vector<string> filelist;

    Size boardSize(6, 4);

    for (int i = 1; i <= 20; i++) {

    stringstream str;

    str << "chessboards\chessboard" <<std::setw(2) << std::setfill('0') << i << ".jpg";

    cout << str.str() << endl;

    filelist.push_back(str.str());

    //                image= cv::imread(str.str(), 0);

    //                cv::imshow("Image",image);

    //

    //                cv::waitKey(100);

    }

    Mat image=imread(filelist[0]);

    CameraCaliberator cameraCaliberator;

    cameraCaliberator.addChessboardPoints(filelist,boardSize);

    cameraCaliberator.calibrate(image.size());

    Matuimage=        cameraCaliberator.remap(image);

    imshow(" ", uimage);

    }

     

    // Openthe video file

    cv::VideoCapturecapture("bike.avi");

    // checkif video successfully opened

    if(!capture.isOpened())

    return 1;

    // Getthe frame rate

    doublerate = capture.get(CV_CAP_PROP_FPS);

    boolstop(false);

    cv::Matframe; // current video frame

    cv::namedWindow("ExtractedFrame");

    // Delaybetween each frame in ms

    //corresponds to video frame rate

    int delay= 1000 / rate;

    // forall frames in video

    while(!stop) {

    // read next frame if any

    if (!capture.read(frame))

    break;

    cv::imshow("Extracted Frame", frame);

    // introduce a delay

    // or press key to stop

    if (cv::waitKey(delay) >= 0)

    stop = true;

    }

    // Closethe video file.

    // Notrequired since called by destructor

    capture.release();

    class FeatureTracker : public FrameProcessor {

    cv::Matgray;                        //current gray-level image

    cv::Matgray_prev;                //previous gray-level image

    std::vector<cv::Point2f> points[2]; // tracked features from0->1

    std::vector<cv::Point2f> initial;   // initial position of tracked points

    std::vector<cv::Point2f> features;  // detected features

    int max_count;          // maximum number of features to detect

    double qlevel;    // qualitylevel for feature detection

    double minDist;   // minimumdistance between two feature points

    std::vector<uchar> status; // status of tracked features

        std::vector<float> err;    // error in tracking

      public:

    FeatureTracker() : max_count(500), qlevel(0.01), minDist(10.) {}

    // processing method

    void process(cv:: Mat &frame, cv:: Mat &output) {

    // convert to gray-level image

    cv::cvtColor(frame, gray, CV_BGR2GRAY);

    frame.copyTo(output);

    // 1. if new feature points must be added

    if(addNewPoints())

    {

    // detect feature points

    detectFeaturePoints();

    // add the detected features to the currently tracked features

    points[0].insert(points[0].end(),features.begin(),features.end());

    initial.insert(initial.end(),features.begin(),features.end());

    }

    // for first image of the sequence

    if(gray_prev.empty())

               gray.copyTo(gray_prev);

               

    // 2. track features

    cv::calcOpticalFlowPyrLK(gray_prev, gray, // 2 consecutive images

    points[0], // input point position in first image

    points[1], // output point postion in the second image

    status,    // tracking success

    err);      // tracking error

              

    // 2. loop over the tracked points to reject the undesirables

    int k=0;

    for( int i= 0; i < points[1].size(); i++ ) {

    // do we keep this point?

    if (acceptTrackedPoint(i)) {

    // keep this point in vector

    initial[k]= initial[i];

    points[1][k++] = points[1][i];

    }

    }

    // eliminate unsuccesful points

            points[1].resize(k);

    initial.resize(k);

    // 3. handle the accepted tracked points

    handleTrackedPoints(frame, output);

    // 4. current points and image become previous ones

    std::swap(points[1], points[0]);

            cv::swap(gray_prev, gray);

    }

    // feature point detection

    void detectFeaturePoints() {

    // detect the features

    cv::goodFeaturesToTrack(gray, // the image

    features,   // the outputdetected features

    max_count,  // the maximumnumber of features

    qlevel,     // quality level

    minDist);   // min distancebetween two features

    }

    // determine if new points should be added

    bool addNewPoints() {

    // if too few points

    return points[0].size()<=10;

    }

    // determine which tracked point should be accepted

    bool acceptTrackedPoint(int i) {

    return status[i] &&

    // if point has moved

    (abs(points[0][i].x-points[1][i].x)+

    (abs(points[0][i].y-points[1][i].y))>2);

    }

    // handle the currently tracked points

    void handleTrackedPoints(cv:: Mat &frame, cv:: Mat &output){

    // for all tracked points

    for(int i= 0; i < points[1].size(); i++ ) {

    // draw line and circle

        cv::line(output,initial[i], points[1][i], cv::Scalar(255,255,255));

    cv::circle(output, points[1][i], 3, cv::Scalar(255,255,255),-1);

    }

    }

    };

    #endif

  • 相关阅读:
    phontomjs debug with webkit inspector
    《Node Web开发》((美)David Herron)【摘要 书评 试读】 京东图书
    PhantomJS in nonheadless mode Google Groups
    Backbone.js
    Underscore.js
    Free HTTP Sniffer: a free HTTP packet sniffer to find the URLs.
    phantomjs node.js parse child process output line by line (spawn) Stack Overflow
    Getting Started · jashkenas/rubyprocessing Wiki
    使用 JSONP 实现跨域通信,第 2 部分: 使用 JSONP、jQuery 和 Yahoo! 查询语言构建 mashup
    JavaScript中的正则表达式
  • 原文地址:https://www.cnblogs.com/Pomodori/p/4316618.html
Copyright © 2020-2023  润新知