OpenCV VideoCapture C ++:读取2帧给出相同的图片

时间:2014-06-26 17:28:01

标签: c++ opencv webcam

我正在编写一个带有for循环的程序,它在for循环的每次迭代中捕获两个不同的帧。我的网络摄像头针对的是不断变化的东西。

for循环的单次迭代中的第一帧和第二帧正如预期的那样彼此不同。然而,很多次(但不是所有时间),for循环的第i次迭代的第2帧看起来与for循环的第(i + 1)次迭代的第1帧完全相同。为什么会这样?这是我的代码......

 #include "opencv2/core/core.hpp"
 #include "opencv2/features2d/features2d.hpp"
 #include "opencv2/nonfree/features2d.hpp"
 #include "opencv2/calib3d/calib3d.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/nonfree/nonfree.hpp"
 #include "opencv2/imgproc/imgproc.hpp"


 #include <iostream>
 #include <fstream>
 #include <sstream>
 #include <stdlib.h>

 using namespace cv;
 using namespace std;


 int main(int argc, const char *argv[]) {
//open webcam to capture video from it
int choice;
cout << " 1. Save frames and homography matrices to file.\n";
cout << " 2. Read in frames and homography matrices from file.\n";
cin >> choice;
 // Choice 1: output
if (choice == 1){
cout << "You picked choice 1!";
VideoCapture cap(0);
if(!cap.isOpened())  
    return -1;

Mat frame1c; // will hold the i'th frame, color
Mat frame1; // ^^, grayscale
Mat frame2c; // will hold the (i+1)'th frame, color
Mat frame2; // ^^, grayscale
std::vector<Mat> theframes; // will hold all the frames
int myvar;
string Hmatrices; // will hold all values of all H matrices.
std::stringstream s;  //used for converting the numerical values to a string

//for(;;){
for(int i = 0; i<10; i++){
// Capture the two frames
    cvWaitKey(500);
    cap.read(frame1c);
    cvWaitKey(200);
    cap.read(frame2c);
    cvWaitKey(200);

    cvtColor(frame1c,frame1,CV_RGB2GRAY);
    cvtColor(frame2c,frame2,CV_RGB2GRAY);

//Detect points on the 2 successive images
    int minHessian = 400;
    SurfFeatureDetector detector(minHessian);
    std::vector<KeyPoint> keypoints1, keypoints2;
    detector.detect(frame1, keypoints1);
    detector.detect(frame2, keypoints2);
// If not enough keypoints are found (e.g. when ThinkPad webcam displays black screen initially),
// then go to the next iteration of the For loop.

    if (keypoints1.size() < 4){
        cout << "   keypoints size <4\n\n";
        continue;
    }

// If the frames have keypoints, save them to "theframes"
    cout << "pushback " << i << " f1c\n";
    theframes.push_back(frame1c.clone());
    cout << "pushback " << i << " f2c\n";
    theframes.push_back(frame2c.clone());

// Calculate feature-vectors of the points
    SurfDescriptorExtractor extractor;
    Mat descriptors1, descriptors2;
    extractor.compute(frame1, keypoints1, descriptors1);
    extractor.compute(frame2, keypoints2, descriptors2);

// Match points on the 2 successive images by comparing feature-vectors
    FlannBasedMatcher matcher;
    std::vector<DMatch> matches;
    matcher.match(descriptors1, descriptors2, matches);
    cout << " all matches size is " << matches.size();

//Eliminate weaker matches
    double maxdist = 0; 
    double mindist = 100;
    for (int j = 0; j < descriptors1.rows; j++){
        double dist = matches[j].distance;
        if( dist < mindist ) mindist = dist;
        if( dist > maxdist ) maxdist = dist;
    }

//build the list of "good" matches
    std::vector<DMatch> goodmatches;
    for( int k = 0; k < descriptors1.rows; k++ ){
        if( matches[k].distance <= 3*mindist ){
            goodmatches.push_back(matches[k]); 
        }
    }


//Now compute homography matrix  between the stronger matches

    //-- Localize the object
    std::vector<Point2f> obj;
    std::vector<Point2f> scene;
    cout << "goodmatches size is " << goodmatches.size();
    unsigned int i;
    std::stringstream s;
    for(int l = 0; l < goodmatches.size(); l++){
    //-- Get the keypoints from the good matches
    obj.push_back(keypoints1[goodmatches[l].queryIdx].pt);
    scene.push_back(keypoints2[goodmatches[l].trainIdx].pt);
    }

    Mat Hmatrix;
    cout << "obj size is " << obj.size();
    Hmatrix = findHomography(obj, scene, CV_RANSAC);

    cout << "found the hmatrix\n";

            //from http://computer-vision-talks.com/articles/2013-06-07-undocumented-opencv/ 
            //The documentation of cv::findHomography does not state it, but return value of cv::findHomography was always 3x3 matrix of CV_64FC1 type
            //cv_64fc1 is type double
            // so can do cout << M.at<double>(0,0), cout << M.at<double>(0,1), etc

// Save the values of the H matrix into the Hmatrices string
    s << Hmatrix.at<double>(0,0) << " ";
    s << Hmatrix.at<double>(0,1) << " ";
    s << Hmatrix.at<double>(0,2) << " ";

    s << Hmatrix.at<double>(1,0) << " ";
    s << Hmatrix.at<double>(1,1) << " ";
    s << Hmatrix.at<double>(1,2) << " ";

    s << Hmatrix.at<double>(2,0) << " ";
    s << Hmatrix.at<double>(2,1) << " ";
    s << Hmatrix.at<double>(2,2) << "\n";
    Hmatrices = Hmatrices + s.str();
    /*
    std::string test = s.str();

    cout << "now printing matrix " << test << " and done"; */

}//end for loop

//std::string tosave = s.str();
cout << "now printing matrix " << Hmatrices << " and done";
ofstream savetofile;
savetofile.open("hmatrices.txt");
Hmatrices.pop_back();
savetofile << Hmatrices;
savetofile.close();

// Save theframes to jpeg files:
for(int m = 0; m<theframes.size(); m++){
    cout << "saving to jpg" << m << "num\n";
    imwrite("frame" + std::to_string((long long)m) + ".jpg", theframes[m]);
    cout << "made it after theframes i \n";
    cout << "inforloop theframes size " << theframes.size() << " that\n";
}
int theint;
cin >> theint;

return 0;}

 //Choice 2: Read in
else{
string filename;
cout << "You picked choice 2!";
cout << "Enter name of file with the homography matrices: ";
cin >> filename;
cout << "\nYou entered the filename " << filename << "\n";

// Read in homography matrices
ifstream readh;
readh.open(filename);
vector <double[3]> hs;
int counter = 0;
int i = 0;
cout << "made it this far";
vector<Mat> thematrices;
double dataforMat [3][3];
while(readh>>dataforMat[0][0]>>dataforMat[0][1]>>dataforMat[0][2]>>dataforMat[1][0]>>dataforMat[1][1]>>dataforMat[1][2]>>dataforMat[2][0]>>dataforMat[2][1]>>dataforMat[2][2]){
    cout << "made it to whileloop iteration number " << i;
    thematrices.push_back(Mat(3,3,CV_64FC1,dataforMat));
    cout << "now printing matrix in mat form..\n";
    cout << thematrices[i];
    cout << "\nfinished printing mat matrix\n";
    i++;
}

int numh = thematrices.size();
vector<Mat> theimages;

// Read in image files, named i.jpg for i = 1,2,3,.....
for(int n = 0; n < numh; n++){
    theimages.push_back(imread("frame" + std::to_string((long long)n) + ".jpg"));
}

    imshow("title",theimages[0]);
    waitKey(1000);

    imshow("title",theimages[1]);
    waitKey(1000);

    imshow("title",theimages[2]);
    waitKey(1000);

    imshow("title",theimages[3]);
    waitKey(1000);

/*
int theint;
cin >> theint;*/

return 0;}
return 0;
}

1 个答案:

答案 0 :(得分:0)

相机的fps是多少?很可能在你循环中你正在从相机读取最后一帧,当你再次尝试再次读取它时(第二次循环)没有新的帧,所以相机给出了最新的帧。
尝试检查帧是否相等,如果是这样,请阅读下一帧,直到你得到“新的东西”。如果您想确保图像相同,请使用subtract函数比较两个图像,而不是调用countNonZero。如果结果为0,则图像相等。