簡體   English   中英

使用v4l2捕獲相機圖像非常慢

[英]Capturing camera image with v4l2 very slow

我一直在努力使用v4l2直接在OpenCV中抓取相機圖像。 這工作得非常好; 通過這種方式,我可以以YUYV格式和高分辨率獲取圖像(了解幀速率將下降)。 我無法通過OpenCV實現完成這項工作。 功能上它的工作效果很好,但性能可能會好得多。 由於這是我第一次直接使用v4l2,它對我來說仍然有點模糊。 我已經對所有相關部分進行了計時,並發現v4l2選擇方法需要花費一秒多的時間。 當我降低時間間隔時,select方法花費的時間更少,但是出列的時間要長得多(也就是第二次)。 在其他功能中,相機被初始化,因此設置正確的格式等。我知道幀速率很低,沒有壓縮和高分辨率,但這是極低的。

下面是捕獲圖像功能。 我跳過了緩沖區轉換為Mat(YUYV - > RGB)的代碼,因為我認為它現在不相關。

有誰知道如何使v4l2捕獲圖像更快? 也許有些部分我不應該執行每個幀抓取?

謝謝!

Mat Camera::capture_image() {
Mat returnframe(10, 10, CV_8UC3);
struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
    perror("Query Buffer");
    return returnframe;
}

if (-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type)) {
    perror("Start Capture");
    return returnframe;
}

fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {0};
tv.tv_sec = 2;
int r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) {
    perror("Waiting for Frame");
    return returnframe;
}

if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
    perror("Retrieving Frame");
    return returnframe;
}

//這里的代碼轉換為Mat

if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &buf.type)) {
    perror("Stop Capture");
    return returnframe;
}

//copy Mat and free bigbuffer, to avoid memory leak
Mat returnImg = dispimg.clone();
free(bigbuffer);
return returnImg;
}

似乎每個幀都調用VIDIOC_STREAMONVIDIOC_STREAMOFF ; 這會增加很多開銷(這幾乎就像為每個幀重新啟動應用程序一樣)

正確的方法是:

  • 打開設備 (僅調用一次):在捕獲會話開始時(例如程序啟動),通過調用VIDIOC_STREAMON設置視頻設備以開始流式傳輸

  • 捕獲幀 (多次調用):對於要捕獲的每個幀,僅通過調用DQBUF / QBUF請求幀(這非常快,因為設備將連續地將數據傳輸到緩沖區隊列中); 您仍然需要調用select才能知道新幀何時可用。

  • 關閉設備 (僅調用一次):完成后,通過調用VIDIOC_STREAMOFF停止流式傳輸

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM