简体   繁体   English

OpenCV VideoCapture C ++:读取2帧图像相同

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

I am writing a program with a for loop that captures two different frames in each iteration of the for loop. 我正在编写一个带有for循环的程序,该程序在for循环的每次迭代中捕获两个不同的帧。 My webcam is directed at something that is constantly changing. 我的网络摄像头针对的是不断变化的事物。

The 1st and second frame within a single iteration of the for loop are different from each other, as expected. 如预期的那样,for循环的一次迭代中的第一帧和第二帧彼此不同。 However, many times (but not all of the time), the 2nd frame of the i'th iteration of the for loop looks the exact same as the 1st frame of the (i+1)th iteration of the for loop. 但是,很多时候(但不是所有时间),for循环的第i次迭代的第二帧看起来与for循环的第(i + 1)次迭代的第一帧完全相同。 Why does this happen? 为什么会这样? Here is my code... 这是我的代码...

 #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;
}

What is the fps of your camera? 相机的fps是多少? It's quite possible that in you loop you are reading the last frame from camera and when you try to read it again (second time in loop) there is no new frame so the camera gives the latest frame. 很有可能在循环播放时,您正在从相机读取最后一帧,而当您尝试再次读取时(循环第二次),则没有新的帧,因此相机会提供最新的帧。
Try to check whether frames are equal and if so read next frame till you get 'something new'. 尝试检查帧是否相等,如果是,请阅读下一帧,直到获得“新内容”为止。 And if you want to be sure that images are equal compare both images using subtract function and than call countNonZero . 如果要确保图像相等,请使用减法函数比较两个图像,然后调用countNonZero If the result will be 0, images are equal. 如果结果为0,则图像相等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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