[英]OpenCV VideoCapture reading issue
这可能是一个愚蠢的问题,但我真的想不通。 首先:抱歉标题含糊不清,我不太确定如何用几句话来描述我的问题。
我在 MS Visual Studio、C++ 中使用 OpenCV 2.4.3。 我正在使用 VideoCapture 界面从我的笔记本电脑网络摄像头捕获帧。
我的程序应该做的是:
为每个姿势循环用户的不同姿势:
这是代码:
int main() {
Mat img, face_img, img_start;
Rect *face;
VideoCapture cam(0);
ofstream fout("dataset/dataset.txt");
if(!fout) {
cout<<"Cannot open dataset file! Aborting"<<endl;
return 1;
}
int count = 0; // Number of the (last + 1) image in the dataset
// Orientations are: 0°, +/- 30°, +/- 60°, +/-90°
// Distances are just two, for now
// So it is 7x2 images
cam.read(img_start);
IplImage image = img_start;
face = face_detector(image);
if(!face) {
cout<<"No face detected..? Aborting."<<endl;
return 2;
}
// Double ROI dimensions
face->x = face->x-face->width / 2;
face->y = face->y-face->height / 2;
face->width *= 2;
face->height *=2;
for(unsigned i=0;i<14;++i) {
// Wait for the user to get in position
getchar();
// Get the face ROI
cam.read(img);
face_img = Mat(img, *face);
// Save it
stringstream sstm;
string fname;
sstm << "dataset/image" << (count+i) << ".jpeg";
fname = sstm.str();
imwrite(fname,face_img);
//do some other things..
我对它的期望:
它的作用:
起初,我在每个 cam.capture() 中都使用了 img,然后我更改了 cam.capture(img_start) 中的第一个,但这没有帮助。 我的代码的第二次迭代保存了应该在第一次保存的图像,第三次迭代保存了应该在第二次保存的图像,依此类推。
我可能遗漏了 VideoCapture 中的一些重要内容,但我真的无法弄清楚,所以我在这里。
感谢您的帮助,我真的很感激。
您实施的问题在于相机不能自由运行并实时捕获图像。 当您启动相机时,视频捕获缓冲区已满,等待您读取帧。 一旦缓冲区已满,在您读取并释放其中的空间之前,它不会为新帧丢弃旧帧。
解决方案是除了“进程”线程之外,还有一个单独的捕获线程。 每当新帧进入时,捕获线程都会从缓冲区中读取帧并将其存储在“最近帧”图像对象中。 当进程线程需要最新的帧时(即当您按下 Enter 键时),它会锁定一个互斥锁以确保线程安全,将最新的帧复制到另一个对象中并释放互斥锁,以便捕获线程继续读取新帧。
#include <iostream>
#include <stdio.h>
#include <thread>
#include <mutex>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void camCapture(VideoCapture cap, Mat* frame, bool* Capture){
while (*Capture==true) {
cap >> *frame;
}
cout << "camCapture finished\n";
return;
}
int main() {
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat *frame, SFI, Input;
frame = new Mat;
bool *Capture = new bool;
*Capture = true;
//your capture thread has started
thread captureThread(camCapture, cap, frame, Capture);
mtx.lock();
imshow(*frame,current_frame);
mtx.unlock();
//Terminate the thread
mtx.lock();
*Capture = false;
mtx.unlock();
captureThread.join();
return 0;
}
这是我根据上述建议编写的代码。 我希望有人能从中得到帮助。
captureObject >> matObject
,将返回图像的最后一帧,而不是捕获卡/网络摄像头中的当前帧。示例代码:用于从网络摄像头捕获最近的屏幕截图。
#include <opencv2/opencv.hpp>
#include <time.h>
#include <thread>
#include <chrono>
using namespace std;
using namespace cv;
int main()
{
struct timespec start, end;
VideoCapture cap(-1); // first available webcam
Mat screenshot;
double diff = 1000;
double fps = ((double)cap.get(CV_CAP_PROP_FPS))/1000;
while (true)
{
clock_gettime(CLOCK_MONOTONIC, &start);
//camera.grab();
cap.grab();// can also use cin >> screenshot;
clock_gettime(CLOCK_MONOTONIC, &end);
diff = (end.tv_sec - start.tv_sec)*1e9;
diff = (diff + (end.tv_nsec - start.tv_nsec))*1e-9;
std::cout << "\n diff time " << diff << '\n';
if(diff > fps)
{
break;
}
}
cap >> screenshot; // gets recent frame, can also use cap.retrieve(screenshot);
// process(screenshot)
cap.release();
screenshot.release();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.