簡體   English   中英

OpenCV VideoCapture C ++:讀取2幀圖像相同

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

我正在編寫一個帶有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 <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;
}

相機的fps是多少? 很有可能在循環播放時,您正在從相機讀取最后一幀,而當您嘗試再次讀取時(循環第二次),則沒有新的幀,因此相機會提供最新的幀。
嘗試檢查幀是否相等,如果是,請閱讀下一幀,直到獲得“新內容”為止。 如果要確保圖像相等,請使用減法函數比較兩個圖像,然后調用countNonZero 如果結果為0,則圖像相等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM