Обнаружение плохих кадров в OpenCV 2.4.9

Я знаю, что название немного расплывчато, но я не знаю, как еще его описать.

CentOS с ffmpeg + OpenCV 2.4.9. Я работаю над простой системой обнаружения движения, которая использует поток с IP-камеры (h264).

Время от времени поток икает и выбрасывает «плохой кадр» (см. Ссылку pic-bad.png ниже). Проблема состоит в том, что эти кадры сильно отличаются от предыдущих кадров и вызывают запуск события «движение», даже если фактическое движение не произошло.

Фотографии ниже объяснят проблему.

Хороший кадр (движение запечатлено):

Хорошая рамка

Плохая рамка (нет движения, просто сломанная рамка):

Bad Frame

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

Благодарю вас!

РЕДАКТИРОВАТЬ ОБНОВЛЕНИЕ:

Фрейм захватывается с помощью программы обнаружения движения C ++ через cvQueryFrame(camera); поэтому я не взаимодействую напрямую с ffmpeg, OpenCV делает это на бэкэнде. Я использую последнюю версию ffmpeg, скомпилированную из git source. Все библиотеки также обновлены (h264 и т. Д., Все скачано и скомпилировано вчера). Данные поступают из потока RTSP (ffserver). Я провел тестирование на нескольких камерах (модели Dahua с 1–3 Мп), и сбои кадров довольно устойчивы во всех них, хотя это не происходит непрерывно, только один раз (например, один раз каждые 10 минут).

7

Решение

При первом подходе мне приходит в голову проверка несоответствия между примером действительного фрейма и тем, который мы проверяем, путем подсчета пикселей, которые не совпадают. Разделив это число на площадь, мы получаем процент, который измеряет различие. Я бы предположил, что выше 0,5 мы можем сказать, что проверенный кадр недействителен, потому что он слишком сильно отличается от примера действительного.

Это предположение подходит только в том случае, если у вас есть статическая камера (она не двигается) и объекты, которые могут двигаться перед ней, находятся не на самом коротком расстоянии (зависит от фокусного расстояния, но если у вас есть, например, широкие линзы, поэтому объекты не должны появляются на расстоянии менее 30 см перед камерой, чтобы предотвратить возникновение ситуации, когда объекты «прыгают» в кадр из ниоткуда и имеют размер, превышающий 50% площади кадра).

Здесь у вас есть функция opencv, которая делает то, что я сказал. Фактически, вы можете отрегулировать коэффициент несоответствия более большим, если считаете, что изменения движения будут происходить быстрее. Обратите внимание, что первый параметр должен быть примером допустимого кадра.

bool IsBadFrame(const cv::Mat &goodFrame, const cv::Mat &nextFrame) {
// assert(goodFrame.size() == nextFrame.size())

cv::Mat g, g2;
cv::cvtColor(goodFrame, g, CV_BGR2GRAY);
cv::cvtColor(nextFrame, g2, CV_BGR2GRAY);

cv::Mat diff = g2 != g;

float similarity = (float)cv::countNonZero(diff) / (goodFrame.size().height * goodFrame.size().width);

return similarity > 0.5f;
}
5

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

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

1

Удалить waitKey(50) или измените его на waitKey(1), Я думаю, что opencv не создает новый поток для выполнения захвата. поэтому, когда возникает пауза, это сбивает с толку процедуры управления буфером, вызывая плохие кадры .. может?

У меня есть камеры dahua и я заметил, что с более высокой задержкой наблюдаются плохие кадры. И они уходят полностью с waitKey(1), Пауза не обязательно должна исходить от waitKey, Процедуры вызова также вызывают такие паузы и приводят к плохим кадрам, если они занимают достаточно много времени.

Это означает, что должна быть минимальная пауза между последовательными захватами кадра. Решение было бы использовать два потока для выполнения захвата и обработки отдельно.

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