Jump to content
Compvision.ru
LexaP

WaitKey(ms) или Sleep(ms), но без визуализации.

Recommended Posts

Коллеги, прошу подсказки. Мониторил форум, не нашел ответов...

Задача.
Считать покадрово видеофайлики с минимум нагрузкой на ЦП. Работа решения планируется на одноплатных ПК без визуализации, то есть в фоновом режиме.

Если считывать кадр и добавить задержку таким способом, нагрузка на ЦП в пределах 0.5%

cv::imshow("ing", img);
cv::waitKey(1000/fps);

Если считывать кадр и добавить задержку так, нагрузка на ЦП в пределах 5.5%

Sleep(1000/fps);

 

Пробовал кучу вариантов.
- Анализ в разных потоках, причем пробовал даже делегировать потоки относительно основного процесса.
- Делал считывание кадров через FFmpeg, типа.

...

avcodec_decode_video2(codec_context, frame, &frame_finished, &packet);

if (frame_finished) {
struct SwsContext * img_convert_ctx;
img_convert_ctx = sws_getCachedContext(NULL, codec_context->width, codec_context->height, codec_context->pix_fmt, codec_context->width, codec_context->height, AV_PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);

sws_scale(img_convert_ctx, ((AVPicture*)frame)->data, ((AVPicture*)frame)->linesize, 0, codec_context->height, ((AVPicture *)pFrameRGB)->data, ((AVPicture *)pFrameRGB)->linesize);

cv::Mat img(frame->height, frame->width, CV_8UC3, pFrameRGB->data[0]); //dst->data[0]);

av_free_packet(&packet);

sws_freeContext(img_convert_ctx);

Sleep(40);
или
cv::imshow("img", img);
cv::waitKey(40);
}
...

- Считывал кадры тоже по разному.

Mat frame;
cap >> frame; 

и так.

cap.grab();
if (!cap.retrieve(frame) || frame.empty())
{continue;}



В общем хоть убей, но при добавление инструкции 

cv::imshow("img", img);
cv::waitKey(40);

Загрузка ЦП оптимальна, но это не то, что нужно в плане реализации., так как планируется работа без визуализации. То есть в конечном итоге желательно установить задержку в Sleep(ms), с сохранением минимальной нагрузки на ЦП.

 

Может есть другие подходы при считывание кадров, добавление задержки и минимальной загрузки ЦП?.

Приоритет: Считать все кадры с минимум нагрузки на ЦП.

Share this post


Link to post
Share on other sites

У меня подозрение на Sleep(), попробуйте просто засунуть его в бесконечный цикл и посмотреть нагрузку. 

Share this post


Link to post
Share on other sites
23 минуты назад, iskees сказал:

У меня подозрение на Sleep(), попробуйте просто засунуть его в бесконечный цикл и посмотреть нагрузку. 

Он и так в цикле, можно конечно поставить Sleep(500), но тогда получим два кадра в сек., что неправильно. Необходимо получать количество кадров равное количеству кадров в видеофайле.

Идеально работает связка cv::imshow и cv::waitKey, но это не то....так как визуализации в фоновой программе нет.

- Может есть информация, что такого есть в cv::imshow и cv::waitKey, чего нет в Sleep()?

- Почему cv::imshow и cv::waitKey дает минимум нагрузки на проц, а Sleep() очень ресурсоёмкий?.. 

PS

Запускал по разному и в разных потоках.

PSS

Проверил Sleep() в цикле, дает 0% нагрузки.

 

 

Share this post


Link to post
Share on other sites

windows под intel i7, сборка в студии

linux под ARM, сборка через cmake ( cmake -DCMAKE_BUILD_TYPE=Release

 сборка и там и там, только в release.

Share this post


Link to post
Share on other sites

А стандартный вариант:

std::this_thread::sleep_for(40ms);

 

Share this post


Link to post
Share on other sites

Тоже самое.

Может cv::waitKey() как то блокирует события в основном потоке и система ждет освобождения ресурсов на уровне получения кадра?. Может еще flush делает какой-то ))

Share this post


Link to post
Share on other sites

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

Пути уменьшения нагрузки 2: увеличивать время простоя или оптимизация узких мест.

P.S. Кстати, если тебе RGB изображение не нужно, то можно оставаться в рамках YUV и убрать sws_scale, нагрузка снизится. Я вообще слабо представляю зачем может понадобиться RGB и откуда он берётся. С камеры получаем raw, который близок к RGB, но не он, а по факту Bayer. Если мы получаем видео с веб-камеры, то там может быть RGB. Если из h264 или jpeg, то уже YUV. Это явно твой случай.

Далее идёт анализ. Куча алгоритмов работают с grayscale картинками. Как мы получаем их? Правильно, конвертируем YUV -> RGB -> Gray. Но можно было просто взять первый Y канал из YUV безо всякого копирования памяти. То есть в привычном сценарии делается две (!!!) лишних конвертации с копированием памяти и потерей данных при этом.

Share this post


Link to post
Share on other sites

Отлично.

Пойду пробовать варианты.

Интересно самому стало.

Спасибо.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×