我一直试图同时从两个不同的相机中抓取帧,但无论我多少次调用VideoCapture :: grab(),似乎都没有效果。使用VideoCapture :: retrieve()检索的帧始终是从上一个VideoCapture :: retrieve()捕获的第一帧。
我在OpenCV 2.4和3.1上都测试了它,在Windows上使用Logitech C920相机。
示例:
<div class="wrap">
<div class="rect-left">
<div class="inner"></div>
</div>
<div class="rect"> <span class="circle"></span>
<div class="avatar"></div>
</div>
<div class="rect-right">
<div class="inner"></div>
</div>
</div>
我也试过了:
VideoCapture vCapture;
Mat imgResult;
vCapture.open(0); //at this point, there is a green sheet in front of the camera
Sleep(100000); //change green sheet with red sheet
vCapture.grab(); //returns true
vCapture.retrieve(imgResult); //image with green sheet is retrieved
Sleep(100000); //change red sheet with blue sheet
vCapture.retrieve(imgResult); //red sheet is retrieved
检索始终返回true并检索一个框架,即使打开vCapture后没有调用任何抓取。
我目前的解决方案是检索帧两次(多线程)以确保最新帧,但它不足以同步两个摄像头。任何人都可以了解如何强迫相机抓住当前帧吗?
谢谢!
编辑:
第一个例子的变体,为清楚起见:
for(int i = 0; i < 1000; i++){
vCapture.grab();
} //takes almost no processing time, like an empty for
vCapture.retrieve(imgResult); //same as before
预期行为:
VideoCapture vCapture;
Mat imgResult;
vCapture.open(0); //at this point, there is a green sheet in front of the camera
vCapture.retrieve(imgResult); //image with green sheet is retrieved
Sleep(100000); //change green sheet with red sheet
vCapture.grab(); //returns true
vCapture.retrieve(imgResult); //green sheet is retrieved
vCapture.retrieve(imgResult); //red sheet is retrieved
Sleep(100000); //change red sheet with blue sheet
vCapture.retrieve(imgResult); //red sheet is retrieved
vCapture.retrieve(imgResult); //blue sheet is retrieved
每个OpenCV文档:
VideoCapture vCapture;
Mat imgResult;
vCapture.open(0); //at this point, there is a green sheet in front of the camera
vCapture.retrieve(imgResult); //error or image with green sheet is retrieved
Sleep(100000); //change green sheet with red sheet
vCapture.grab(); //returns true
vCapture.retrieve(imgResult); //red sheet is retrieved
:方法/函数从视频文件或摄像机中获取下一帧,并在成功的情况下返回true(非零)。
VideoCapture::grab
:方法/函数解码并返回刚捕获的帧。如果没有抓取帧(摄像机已断开连接,或视频文件中没有帧),则方法返回false,函数返回NULL指针。
答案 0 :(得分:2)
请按照以下说明尝试此代码:
在启动程序之前和之后,请在相机前面放一张红色的纸张。那一刻,第一个.grab将被召唤。
一旦看到黑色窗口弹出,请取下红色表并在相机前面放一块蓝色的纸或其他东西(红色或绿色纸除外)。然后按键盘键&#39; q&#39;
现在您有5秒的时间再次更改场景。握住相机前面的绿色纸张等待。黑色窗口将切换到您的一个相机图像。
int main(int argc, char* argv[])
{
cv::Mat input = cv::Mat(512,512,CV_8UC1, cv::Scalar(0));
cv::VideoCapture cap(0);
while (cv::waitKey(10) != 'q')
{
cap.grab();
cv::imshow("input", input);
}
cv::waitKey(5000);
cap.retrieve(input);
cv::imshow("input", input);
cv::waitKey(0);
return 0;
}
3个可能的结果:
你看到红色表格:这意味着调用了第一个抓取并修复了图像,直到调用了检索。
你看到蓝色表:这意味着每个.grab电话&#34;删除&#34;一个图像和相机将在下次调用.grab
你看到绿色表:这意味着你的.retrieve根本不需要.grab并且只是自动抓取图像。
对我来说,结果1出现了,所以你不能抓住并抓住并且只是.retrieve最后一张图片。
测试2:控制一切:
.retrieve
时调用的图像和{{1根本不会影响捕获的时间位置。对于不同(所有)类型的相机和操作系统是否会出现相同的行为会非常有趣。
我已经在T450和Windows 7的内置摄像头上进行了测试。
.grab
另外,对于我的相机来说,这个简单的代码似乎是1帧(因此可能有2个缓冲区大小):
int main(int argc, char* argv[])
{
cv::Mat input = cv::Mat(512,512,CV_8UC1, cv::Scalar(0));
cv::VideoCapture cap(0);
bool grabbed;
bool retrieved;
while (true)
{
char w = cv::waitKey(0);
switch (w)
{
case 'q': return 0;
case 27: return 0;
case ' ': retrieved = cap.retrieve(input); break;
case 'p': grabbed = cap.grab(); break;
}
cv::imshow("input", input);
}
return 0;
}
答案 1 :(得分:0)
我运行了测试并注意到.garab和.retrive函数的非常奇怪的行为。 这是一个例子:
cv::Mat input = cv::Mat(512, 512, CV_8UC1, cv::Scalar(0));
cv::VideoCapture cap(0);
while (true)
{
cap.grab();
cap.retrieve(input, 5);
cv::imshow("input", input);
cv::waitKey(0);
}
如果你慢慢地按任意键,大约每5秒钟一次,并在按下之前改变相机前面的某些东西,图像上物体的位置将改变每一秒显示的图像,即每秒钟的一次调用。抓住和.retrive功能。
如果您快速按任意键,大约每1秒钟,并且在按下之间也会更改相机前面的某些内容,则每个显示的图像都会更改图像上对象的位置。
这种情况表明此功能可用于同步相机。