OpenCV VideoCapture c++:读取2帧得到相同的图像

OpenCV VideoCapture C++: reading 2 frames gives the same picture

本文关键字:图像 2帧 VideoCapture c++ 读取 OpenCV      更新时间:2023-10-16

我正在编写一个for循环程序,该程序在for循环的每次迭代中捕获两个不同的帧。我的网络摄像头对准的是不断变化的事物。

在for循环的单个迭代中的第一帧和第二帧彼此不同,正如预期的那样。然而,很多时候(但不是所有时候),for循环的第i次迭代的第二帧看起来与for循环的(i+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 <4nn";
        continue;
    }
// If the frames have keypoints, save them to "theframes"
    cout << "pushback " << i << " f1cn";
    theframes.push_back(frame1c.clone());
    cout << "pushback " << i << " f2cn";
    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 hmatrixn";
            //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 << "numn";
    imwrite("frame" + std::to_string((long long)m) + ".jpg", theframes[m]);
    cout << "made it after theframes i n";
    cout << "inforloop theframes size " << theframes.size() << " thatn";
}
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 matrixn";
    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;
}

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