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 <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,则图像相等。
相关文章:
- 使用命名管道将图像帧从服务器发送到 C# 客户端C++
- 使用 GTK 将 EGL 图像渲染到帧缓冲区
- 修改思科 openh264 以拍摄图像帧和压缩帧
- 如何将图像帧相机传递给wasm (C++)中的函数?
- 从C++图像帧到客户端浏览器中的 html5 <视频标记
- Haar检测-保存图像的Mat,以便获得并显示前一帧
- 在Qt/QML中的每一帧更新图像时运行时崩溃
- 在visual Studio 2012上使用SDL加载.BMP图像时,它只显示一个帧
- 使用FFmpeg解码视频帧时获取的撕裂图像
- 分层图像作为具有大量层的帧缓冲
- 使用 FLTK & C++:制作适合定义帧内图像的功能
- 不保存任何图像。保存视频帧时
- 如何使用OpenCV或其他图像处理库从RGB数据写入YUV420视频帧
- 用C/C++编写YUV图像帧的问题
- 如何根据C++程序中生成的多个图像对视频进行编码,而不将单独的帧图像写入磁盘
- 如何知道帧或图像的大小
- 尝试在C++中使用OpenCV从灰度相机渲染图像.几帧后就挂了
- 图像在第一帧后消失,iOS,OpenGL
- 在多帧图像中插入修改过的像素数据
- LibVLC从帧/图像创建流