gpt4 book ai didi

c++ - OpenCV grab 在网络摄像头上什么都不做

转载 作者:太空宇宙 更新时间:2023-11-03 22:26:33 24 4
gpt4 key购买 nike

我一直在尝试同时从两个不同的相机抓取帧,但无论我调用多少次 VideoCapture::grab(),似乎都没有效果。使用 VideoCapture::retrieve() 检索的帧始终是从最后一个 VideoCapture::retrieve() 捕获的第一帧。

我已经在 OpenCV 2.4 和 3.1 上测试过它,在 Windows 上使用罗技 C920 摄像头。

例子:

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

我也试过:

for(int i = 0; i < 1000; i++){
vCapture.grab();
} //takes almost no processing time, like an empty for
vCapture.retrieve(imgResult); //same as before

即使自打开 vCapture 后未调用抓取,检索始终返回 true 并检索帧。

我目前的解决方案是两次检索帧(多线程)以确保最新帧,但它不够可靠,无法同步两个摄像头。谁能阐明如何强制相机抓取当前帧?

谢谢!

编辑:

为清楚起见,第一个示例的变体:

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

预期行为:

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

根据 OpenCV 文档:

VideoCapture::grab:方法/函数从视频文件或相机中抓取下一帧,并在成功时返回 true(非零)。

VideoCapture::retrieve:方法/函数解码并返回刚刚抓取的帧。如果没有抓取帧(相机已断开连接,或者视频文件中没有更多帧),方法返回 false,函数返回 NULL 指针。

最佳答案

请按照以下说明尝试此代码:

  1. 在启动程序之前和期间,在镜头前拿一张红纸。那一刻,第一个 .grab 将被调用。

  2. 一旦看到弹出的黑色窗口,请取下红色纸,并在相机前拿一张蓝色纸或其他东西(红色或绿色纸除外)。然后按键盘键“q”。

  3. 现在您有 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 种可能的结果:

  1. 您会看到红色表格:这意味着调用了第一次抓取并修复了图像,直到调用了检索。

  2. 您会看到蓝表:这意味着每次 .grab 调用都会“删除”一张图像,而相机将在下一次调用 .grab 时捕获一张新图像

  3. 您会看到绿页:这意味着您的 .retrieve 根本不需要 .grab,只是自动抓取图像。

对我来说,结果 1 出现了,所以你不能抓啊抓啊抓啊抓,只是.检索最后一张图像。


测试 2:控制一切:

  • 看起来你是对的,在我的机器上,无论我何时或多久调用 grab,下一张图像都将是我调用前一个 .retrieve 和调用时捕获的图像.grab 似乎根本不影响捕获的时间位置。

不同(所有)类型的相机和操作系统是否会出现相同的行为,这将非常有趣。

我已经在 T450s 和 Windows 7 的内置摄像头上进行了测试。

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 帧(因此它的缓冲区大小可能为 2??):

while (true)
{
cap >> input;

cv::imshow("input", input);
cv::waitKey(0);
}

关于c++ - OpenCV grab 在网络摄像头上什么都不做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36913733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com