OpenCV: VideoCapture :: get (CV_CAP_PROP_FPS) возвращает 0 FPS

Я пытаюсь получить fps от моей камеры, чтобы я мог передать его VideoWriter для вывода видео. Тем не менее, я получаю 0 кадров в секунду, позвонив VideoCapture::get(CV_CAP_PROP_FPS) с моей камеры. Если я жестко закодирую его, моё видео может быть слишком медленным или слишком быстрым.

#include "opencv2/opencv.hpp"#include <stdio.h>
#include <stdlib.h>

using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{
cv::VideoCapture cap;
int key = 0;

if(argc > 1){
cap.open(string(argv[1]));
}
else
{
cap.open(CV_CAP_ANY);
}
if(!cap.isOpened())
{
printf("Error: could not load a camera or video.\n");
}

Mat frame;
cap >> frame;
waitKey(5);

namedWindow("video", 1);
double fps = cap.get(CV_CAP_PROP_FPS);
CvSize size = cvSize((int)cap.get(CV_CAP_PROP_FRAME_WIDTH),(int)cap.get(CV_CAP_PROP_FRAME_HEIGHT));

int codec = CV_FOURCC('M', 'J', 'P', 'G');
if(!codec){ waitKey(0); return 0; }
std::cout << "CODEC: " << codec << std::endl;
std::cout << "FPS: " << fps << std::endl;
VideoWriter v("Hello.avi",-1,fps,size);
while(key != 'q'){
cap >> frame;
if(!frame.data)
{
printf("Error: no frame data.\n");
break;
}
if(frame.empty()){ break; }
v << frame;
imshow("video", frame);
key = waitKey(5);
}
return(0);
}

Как я могу получить VideoCapture::get(CV_CAP_PROP_FPS) вернуть правильный fps или дать fps VideoWriter это работает универсально для всех веб-камер?

10

Решение

Насколько я знаю, CV_CAP_PROP_FPS работает только с видео. Если вы хотите захватывать видеоданные с веб-камеры, вы должны правильно рассчитать время. Например, используйте таймер для захвата кадра с веб-камеры каждые 40 мс, а затем сохраняйте видео со скоростью 25 кадров в секунду.

4

Другие решения

Ты можешь использовать VideoCapture::set(CV_CAP_PROP_FPS) установить желаемый FPS для веб-камеры. Однако по какой-то причине вы не можете использовать get.

Обратите внимание, что иногда драйвер выбирает другой FPS, чем тот, который вы запрашивали, в зависимости от ограничений веб-камеры.

Мой обходной путь: захватывать кадры в течение нескольких секунд (в моих тестах 4 — это нормально, с начальной задержкой 0,5 секунды) и оценивать частоту кадров камеры.

2

Я никогда не наблюдала CV_CAP_PROP_FPS работать. Я пробовал с различными вариантами OpenCV 2.4.x (в настоящее время 2.4.11), используя входные данные файла.

В качестве обходного пути в одном сценарии я непосредственно использовал libavformat (из ffmpeg), чтобы получить частоту кадров, которую затем я могу использовать в своем другом коде OpenCV:

static double get_frame_rate(const char *filePath) {
AVFormatContext *gFormatCtx = avformat_alloc_context();
av_register_all();

if (avformat_open_input(&gFormatCtx, filePath, NULL, NULL) != 0) {
return -1;
} else if (avformat_find_stream_info(gFormatCtx, NULL) < 0) {
return -1;
}

for (int i = 0; i < gFormatCtx->nb_streams; i++) {
if (gFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
AVRational rate = gFormatCtx->streams[i]->avg_frame_rate;
return (double)av_q2d(rate);
}
}

return -1;
}

Помимо этого, несомненно, один из самых медленных (хотя и обязательно работающих) методов, позволяющих получить среднее число кадров в секунду, состоит в том, чтобы проходить через каждый кадр и делить номер текущего кадра на текущее время:

for (;;) {
currentFrame = cap.get(CV_CAP_PROP_POS_FRAMES);
currentTime = cap.get(CV_CAP_PROP_POS_MSEC);
fps = currentFrame / (currentTime / 1000);

# ... code ...
# stop this loop when you're satisfied ...
}

Вы, вероятно, захотите сделать последнее только в том случае, если другие методы непосредственного нахождения fps не будут выполнены, и, кроме того, не было лучшего способа получить общую информацию о длительности и количестве кадров.

Приведенный выше пример работает с файлом — для адаптации к камере вы можете использовать время, прошедшее с начала захвата с начала захвата, вместо получения CV_CAP_PROP_POS_MSEC, Тогда среднее число кадров в секунду для сеанса будет представлять собой истекшее время настенных часов, деленное на номер текущего кадра.

1

Для живого видео с веб-камеры используйте cap.get (cv2.CAP_PROP_FPS)

0
По вопросам рекламы [email protected]