Ответ Алексея Петрова неплохой, но, хотя усреднение по последним N кадрам дает более плавные значения, можно относительно точно измерить частоту кадров без усреднения. Вот код вопроса, модифицированный для этого:
// see question for earlier code
Mat frame, raw;
time_type prevTimePoint; // default-initialized to epoch value
while (waitKey(1) != 'q') {
capture >> raw;
auto timePoint = std::chrono::high_resolution_clock::now();
if (raw.empty()) {
return 1;
}
if (raw.channels() > 1) {
cv::cvtColor(raw, frame, CV_BGR2GRAY);
} else {
frame = raw;
}
showFPS(&frame, prevTimePoint, timePoint);
cv::imshow("frame", frame);
}
return 0;
}
void showFPS(Mat* frame, time_type &prevTimePoint, const time_type &timePoint) {
if (prevTimePoint.time_since_epoch().count()) {
std::chrono::duration<float> duration = timePoint - prevTimePoint;
cv::putText(*frame, "FPS: " + std::to_string(1/duration.count()),
cv::Point2f(20, 40), 2, 2, cv::Scalar(0,255,0));
}
prevTimePoint = timePoint;
}
Обратите внимание, что это измеряет момент времени сразу после возврата capture >> raw
, который (без вмешательства в OpenCV) является самым близким, когда камера отправляет кадр, и что время измеряется только один раз за цикл и сравнивается по сравнению с предыдущим измерением, которое дает довольно точную текущую частоту кадров. Конечно, если обработка занимает больше времени, чем 1 / (частота кадров), измерение будет отключено.
Причиной того, что код вопроса дал слишком высокую частоту кадров, был код между двумя измерениями времени: now()
в showFPS()
и now()
в цикле while
. Я догадываюсь, что этот код включает cv::imshow()
, который не рассматривается, и который вместе с cv::waitKey(5)
и cv::putText()
, вероятно, ответственен за большую часть "пропущенного времени" в расчете частоты кадров (вызывая слишком высокую частоту кадров ).