2014-06-26 139 views
0

我正在編寫一個for循環程序,它在for循環的每次迭代中捕獲兩個不同的幀。我的攝像頭針對的是不斷變化的東西。OpenCV VideoCapture C++:讀取2個幀給出相同的圖片

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; 
} 
+0

如果它發生在隨機時間間隔那麼它可能是你觀察的對象在那段時間內沒有改變。你可以通過獲得你得到的矩陣的差異來驗證它,看看它是否恰好爲零? –

回答

0

什麼是你的相機的fps?很可能,在循環中,您正在讀取來自相機的最後一幀,並且當您嘗試再次讀取時(第二次循環),則沒有新幀,因此相機會給出最新幀。
嘗試檢查幀是否相等,如果是這樣,請閱讀下一幀,直到獲得「新的東西」。如果你想確保圖像是相同的,使用subtract函數比較這兩個圖像,然後調用countNonZero。如果結果爲0,則圖像相等。