这可能是一个愚蠢的问题,但我真的无法弄清楚。 首先:对于模糊的标题感到抱歉,我不确定如何用几个词来描述我的问题。
我在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)中更改了第一个,但这没有帮助。 我的代码的第二次迭代保存了应该在第1次迭代中保存的图像,第3次迭代应该保存在第2次中的图像,依此类推。
我可能错过了VideoCapture的一些重要内容,但我真的无法理解,所以我在这里。
感谢您的帮助,我真的很感激。
答案 0 :(得分:1)
您的实施问题是相机无法自由运行并实时捕捉图像。当您启动相机时,视频捕捉缓冲区会在等待您读取帧时填满。一旦缓冲区已满,它就不会丢弃旧帧,直到你读取并释放其中的空间。
除了“进程”线程之外,解决方案是拥有一个单独的捕获线程。每当新帧进入时,捕获线程都会从缓冲区继续读取帧,并将其存储在“最近帧”图像对象中。当进程线程需要最新的帧时(即当你按Enter键时),它会锁定互斥锁以保证线程安全,将最近的帧复制到另一个对象并释放互斥锁,以便捕获线程继续读取新帧。
答案 1 :(得分:0)
#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;
}
这是我从上述建议中编写的代码。我希望有人能从中得到帮助。
答案 2 :(得分: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;
}