Jump to content
Compvision.ru
al072

Плывет изображение

Recommended Posts

Всем доброго времени суток! Столкнулся с проблемой. Тестирую код из книги Mastering OpenCV глава 8. И не пойму по какой причине видео с вебкамеры начинает тормозить (задержка примерно 3 сек)  и искажаться через определенное время (10-30 сек) после запуска режима распознавания лица. То есть в режимах когда идет сбор лиц или просто режим определения, картинка не тормозит и не искажается, но как только включаю режим распознавания лица начинаются проблемы (файл прикрепил).

1) Пробовал запихать цикл распознавания в таймер. не помогло.

2) Пробовал запускать в отдельном потоке (выставлял разные Sleep(1-30)). не помогло.

3) Пробовал выводить изображение как через функцию imshow, так и на форму (MFC C++), тоже не дало результатов.

4) Утечка памяти замечена не была.

Если кто-нибудь сталкивался с подобной проблемой, подскажите плиз как ее решить?

 

Безымянный.jpg

Share this post


Link to post
Share on other sites

А если убрать все кроме потока камера - экран?

Также размазывает?

Вообще очень похоже на проблемы кодека.

Share this post


Link to post
Share on other sites

Нет, если оставить просто вывод видео на экран с камеры, то работает быстро без проблем не тормозит. Но как только включается функция распознавания, начинаются проблемы. 

Похоже на то, что проблема в камере ( я использую Foscam 9831P) и rtsp видеопоток (h264, 15 fps, 640x480, 1mb bitrate). Пробовал переключать на substream (mjpeg), но почемуто с mjpeg вообще начинаются жесткие тормоза, причем просто при выводе изображения без обработки.

Когда использую встроенную в ноутбук web камеру, подобных проблем не возникает.

Smorodov, если возможная проблема в кодеках, то в какую сторону копать?

Share this post


Link to post
Share on other sites

С кодеками проблема рещается только поиском подходящих кодеков :)

А пробовали вырубать часть распознавателя и смотреть какой кусок кода вредоносит?

Share this post


Link to post
Share on other sites

Речь идет о кодеках на видеокарту ноутбука? Куда эти кодеки необходимо устанавливать? Или надо какимто образом их к проекту прикручивать?

Пробовал методом исключения. 

1. Режим сбора лиц. Работает нормально.

2. Режим определения лиц. Работает нормально.

3. В куске кода где идет распознавание лица начинаются проблемы. Где именно не могу диагностировать, так как программа не вылетает и какие либо явные ошибки не появляются. Сперва думал что проблемы в методе отрисовки изображения на форме, но потом начал тестировать стандартный imshow. результат такойже, изображение плывет. 

 

 

Share this post


Link to post
Share on other sites

А если вставить тупо загрузку процессора? Типа цикла, вычисляющего что-нибудь бессмысленное в течение нескольких миллисекунд.

Share this post


Link to post
Share on other sites
1 час назад, Nuzhny said:

А если вставить тупо загрузку процессора? Типа цикла, вычисляющего что-нибудь бессмысленное в течение нескольких миллисекунд.

В какую часть кода это необходимо вставить? 

Share this post


Link to post
Share on other sites

Вообщем начал исследовать проблему дальше и заметил следующее. Если на этапе сбора лиц для распознавания, собрать например 10-15 лиц на одного человека, то на этапе распознавания картинка не плывет. Если собрать 50 и более лиц, то на этапе когда включаю распознавание, начинаются описанные тормоза и искажение изображения. 

Возможно функция predict начинает дольше искать соответствия и начинается рассинхрон.. Установка пакета кодеков (Mega K-lite kodec pack) c настройками по дефолту не помогла. Господа подскажите плиз в чем может быть проблема?

Share this post


Link to post
Share on other sites
5 hours ago, al072 said:

В какую часть кода это необходимо вставить? 

Между кадрами вместо распознавания лиц. Проблемы у тебя очевидно из-за того, что ты вычисляешь дольше, чем 1000 / fps миллисекунд. Или задержку между кадрами ставь не постоянную а в зависимости от загрузки.

Share this post


Link to post
Share on other sites

Nuzhny, можете подсказать как выставить задержку в зависимости от загрузки?

Share this post


Link to post
Share on other sites

Ну, у тебя же есть код с распознаванием лиц. Перед ним делаешь cv::GetTickCount, после него тоже. Смотришь разницу - как долго проработало  распознавание. Переводишь в миллисекунды.

И выставляешь вэйт на интервал между кадрами - время работы.

Примерно так:

int fps = static_cast<int>(capture.get(CV_CAP_PROP_FPS));
if (fps < 1)
{
    fps = 25;
}
                    
for (; capture >> frame;)
{
    int64 t1 = cv::getTickCount();
    // Work with frame
    int64 t2 = cv::getTickCount();
    double freq = cv::getTickFrequency();
    int workTime = static_cast<int>(1000. * (t2 - t1) / freq);
    int waitTime = (workTime >= 1000 / fps) ? 1 : (1000 / fps - workTime);
    if (cv::waitKey(waitTime) > 0)
    {
          break;
    }
}

 

  • Like 1

Share this post


Link to post
Share on other sites

Большое спасибо за пример. Вечером буду пробовать. Отпишусь по результатам.

Share this post


Link to post
Share on other sites

 

Nuzhny, ваш совет помог сделать вывод изображения на форму намного стабильнее! В процессе когда идет распознавание лица перестало тормозить видео. Когда собираю до 100 лиц в коллекцию работает нормально, при 110-120 лицах изображение начинает плыть(  то есть добавляю три человека, на каждого человека по 30 лиц, запускаю распознавание, все работает. Затем добавляю 4-го человека и еще 30 лиц, и спустя определенное время (10-20 секунд) начинает опять плыть изображение.

 

Еще странное значение выдается по fps камеры. В настройках самой камеры выставлено:

15 fps, 1m bitrate, resolution 640x480, key frame interval 60

Следующий код выдает значение fps = 90000.

int fps = static_cast<int>(capture.get(CV_CAP_PROP_FPS));
if (fps < 1)
{
    fps = 25;
}

Мне пришлось вручную выставлять значение fps = 15 в коде, так как выдаваемое  функцией capture.get(CV_CAP_PROP_FPS) значение не реальное. Ведь fps не может быть 90000 правильно? Или я ошибаюсь?

Когда в настройках камеры выставляю значение fps =25, изображение начинает плыть даже при простом выводе на форму, без распознавания. Не могу понять связь между тем, что до 100 лиц программа работает нормально, после 100 лиц начинает плыть. Разве 10-20 дополнительных лиц могут так задерживать процесс обработки изображения? И даже если бы начинались задержки, для этого и был добавлен код getTickcount() чтобы синхронизировать работу цикла с помощью автоматически регулируемого 

 if (cv::waitKey(waitTime) > 0)

Может еще какие мысли у кого будут по данной проблеме?

 

 

Share this post


Link to post
Share on other sites

Да, с выдачей fps что-то не так, но вручную выставленное 15 тоже пойдёт.

Почему плывёт уже понятно? Из-за высокой загрузки. Видимо, не укладывается в интервал 60 мс.

Что же делать? Вариантов несколько.

1. Использовать обработку в отдельном потоке: получил кадр, засунул его в очередь, а второй поток её разгребает и, если она становится слишком большой, выкидывает некоторые кадры без обработки.

2. Использовать многоядерность для алгоритмов. То есть найти медленное место и распараллелить хотя бы с помощью openmp.

3. Ускорить медленное место с помощью задействования GPU.

Я бы 100% реализовал пункт 1, а остальные при необходимости, если размер очереди будет сильно расти.

  • Like 1

Share this post


Link to post
Share on other sites

Спасибо за рекомендации. Тогда пойду путем номер 1.

Я так понимаю что в C++ MFC нет стандартных классов для реализации очереди потоков? Можете посоветовать каким образом лучше это реализовать?

Share this post


Link to post
Share on other sites

std::thread из стандарта С++11

  • Like 1

Share this post


Link to post
Share on other sites

Вообще, последовательность должна быть несколько иной, нужно вынести за скобки тяжелые действия, такие как добавление лиц в базу и распознавание, повесить их на какие нибудь события.

Как вариант предлагаю:

1) Детектировать лица.

2) Инициализировать/апдейтить трекинг.

3) По событию (нажатие кнопки) добавление в базу.

4) По событию (начало трека например), запускается поток по распознаванию трекаемых лиц, которое выполняется один раз. По результатам назначаются метки трекам. 

5) Пока трек не сорвался не делаем лишних движений, просто трекаем. Очень маловероятно, что лицо сменится без срыва трека.

 

  • Like 1

Share this post


Link to post
Share on other sites

Добрый вечер!

1) Копаю проблему дальше.. Изображение плывет из-за следующих ошибок, в каком месте кода они возникают я не пойму, так как не могу их перехватить, но судя по всему ошибки возникают при чтении фрейма videoCapture >> cameraFrame; В проекте MFC я эти ошибки не вижу, но если запустить тот же самый код в консольном проекте, то в консольном окне в момент когда плывет изображение появляются ошибки (скриншоты прикрепил). Может ктонибудь сказать в чем может быть проблема?

2) Nuzhny, я пишу проект в VS2010, там нет std::thread. есть варианты реализации очереди для более старой версии языка? Думаю что от проблемы с искажением изображения можно будет уйти без очереди потоков, если получиться разобраться из-за чего сыпятся ошибки и что они означают..

Ошибка.jpg

Ошибка2.jpg

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Больше похоже на потерю ключевых кадров. Камера может выдавать mjpeg? Проверь с ним.

 

  • Like 1

Share this post


Link to post
Share on other sites

Mjpeg выдавать может, но с ним вообще жуткие тормоза. Очень низкая скорость при VideoCapture.open(mjpeg stream). Хотя если открываю тот же поток в браузере или vlc летает как сумасшедший. Без задержек и проблем.

Share this post


Link to post
Share on other sites

Ты же ffmpeg вернул?

 

Share this post


Link to post
Share on other sites

Да ffmpeg вернул. С mjpeg потоком у меня изначально были такие траблы. Как с выключенным так и с включенным ffmpeg. По этому я перешел на rtsp h.264. 

Share this post


Link to post
Share on other sites
В 05.02.2016 at 14:23, Smorodov said:

Вообще, последовательность должна быть несколько иной, нужно вынести за скобки тяжелые действия, такие как добавление лиц в базу и распознавание, повесить их на какие нибудь события.

Как вариант предлагаю:

1) Детектировать лица.

2) Инициализировать/апдейтить трекинг.

3) По событию (нажатие кнопки) добавление в базу.

4) По событию (начало трека например), запускается поток по распознаванию трекаемых лиц, которое выполняется один раз. По результатам назначаются метки трекам. 

5) Пока трек не сорвался не делаем лишних движений, просто трекаем. Очень маловероятно, что лицо сменится без срыва трека.

 

smorodov, не совсем понял что имеется ввиду под определением

1) инициализировать/апдейтить трекинг

2) что подразумевается под "назначаются метки трекам"?

3) как определяем что трек сорвался?

Спасибо.

Share this post


Link to post
Share on other sites

Я как то делал трекер, думаю он Вам подойдет (метки здесь обозначены разными цветами).

Исходники: https://github.com/Smorodov/Multitarget-tracker

  • Like 1

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.

×