Как обнаружить движущийся объект в различных условиях освещения (освещенности) из-за облаков - openCV

Я пытался обнаружить движущиеся транспортные средства. Но из-за различных условий освещения из-за облаков (не теней от облаков, а только освещения) вычитание фона не удается.

Я загрузил сюда свое входное видео --> Youtube (30 сек.)

Вот что я получил, используя различные доступные методы вычитания фона, доступные в opencv

import numpy as np
import cv2

cap = cv2.VideoCapture('traffic_finalns.mp4')
#fgbgKNN = cv2.createBackgroundSubtractorKNN()
fgbgMOG = cv2.bgsegm.createBackgroundSubtractorMOG(100,5,0.7,0)
#fgbgGMG = cv2.bgsegm.createBackgroundSubtractorGMG()
#fgbgMOG2 = cv2.createBackgroundSubtractorMOG2()
#fgbgCNT = cv2.bgsegm.createBackgroundSubtractorCNT(15,True,15*60,True)

 while(1):
    ret, frame = cap.read()
#   fgmaskKNN = fgbgKNN.apply(frame)
    fgmaskMOG = fgbgMOG.apply(frame)
#   fgmaskGMG = fgbgGMG.apply(frame)
#   fgmaskMOG2 = fgbgMOG2.apply(frame)
#   fgmaskCNT = fgbgCNT.apply(frame)
#   
#   cv2.imshow('frame',frame)
#   cv2.imshow('fgmaskKNN',fgmaskKNN)
    cv2.imshow('fgmaskMOG',fgmaskMOG)
#   cv2.imshow('fgmaskGMG',fgmaskGMG)
#   cv2.imshow('fgmaskMOG2',fgmaskMOG2)
#   cv2.imshow('fgmaskCNT',fgmaskCNT)

    k = cv2.waitKey(20) & 0xff
    if k == 27:
        break


cap.release()
cv2.destroyAllWindows()

(ниже изображений -> номер кадра - 977)

  • BackgroundSubtractorMOG: изменяя входной параметр history, можно уменьшить некоторое освещение, но не все, так как продолжительность освещения является переменной введите здесь описание изображения

  • BackgroundSubtractorMOG2: введите описание изображения здесь

  • BackgroundSubtractorGMG: введите здесь описание изображения

  • **BackgroundSubtractorKNN: ** введите здесь описание изображения

  • BackgroundSubtractorCNT введите здесь описание изображения


person Severus Tux    schedule 24.03.2018    source источник


Ответы (1)


1] Улучшение результатов с помощью вычитания фона OpenCV

  • Для различных условий освещения важно нормализовать ваши пиксельные значения от 0 до 1. В вашем коде я не вижу, чтобы это происходило
  • Вычитание фона не будет работать с одним изображением (в вашем коде вы читаете изображение)
  • Если вы применяете вычитание фона к последовательности кадров, то первый кадр результата вычитания фона бесполезен.
  • вы можете настроить аргументы cv2.bgsegm.createBackgroundSubtractorMOG(), которые вы передаете, чтобы получить наилучшие результаты... Поиграйте с порогом и посмотрите, какие результаты вы получите
  • Вы также можете применить фильтр Гаусса к отдельным кадрам, чтобы уменьшить шум и получить лучшие результаты cv2.GaussianBlur()
  • Вы можете попробовать cv2.equalizeHist() на отдельном кадре, чтобы улучшить контрастность кадров.

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

2] Используйте tensorflow API для обнаружения объектов

  • Он выполняет обнаружение объектов в режиме реального времени, а также дает координаты ограничивающей рамки обнаруженных объектов.

  • Вот результаты API обнаружения объектов Tensorflow: введите здесь описание изображения

3] Как насчет того, чтобы попробовать Opencv Optical Flow< /сильный>

4] Простое вычитание

  • Ваша среда статична
  • Итак, возьмите кадр вашей среды и сохраните его в переменной, скажем, environment_frame
  • Теперь прочитайте каждый кадр из вашего видео и просто вычтите его из кадра окружения results = environment_frame - current_frame.
  • Теперь, если np.sum(results) больше порогового значения, мы говорим, что объект есть.
  • Теперь, если np.sum(results) больше порога, мы знаем, что есть движущийся объект, но где ???
  • Движущийся объект — это место, где есть сгруппированные загроможденные пиксели, которые вы можете легко найти с помощью некоторого алгоритма кластеризации.
  • Не забудьте нормализовать значения пикселей между 0 и 1.

---------------------------------------------------------ОБНОВЛЕНО------------------ ----------------------

  • Если вы хотите находить шлемы в режиме реального времени, лучше всего использовать глубокое обучение.
  • Вы можете использовать метод глубокого обучения, такой как YOLO, какая более новая версия у OpenCV есть... но я не думаю, что у них есть привязка python для YOLO в OpencV
  • Другим методом реального времени может быть RCNN, который уже есть в API обнаружения объектов тензорного потока.... Я упомянул об этом выше.
  • Если вы хотите использовать традиционные методы компьютерного зрения, вы можете попробовать hog и svm для данных шлема, а затем вы можете попробовать метод скользящего окна, чтобы найти шлем в вашем кадре (это не будет в реальном времени)
person Jai    schedule 24.03.2018
comment
Спасибо :), попробую нормализовать. Кстати, я прокомментировал цикл while, исправлено сейчас - person Severus Tux; 24.03.2018
comment
Мое главное намерение состоит не в том, чтобы обнаруживать движущиеся объекты, я пытаюсь разработать обнаружение мотоциклетного шлема, для этого я имею в виду обнаружение движущихся объектов --> классификация --> Извлечение ROI каждого мотоцикла --> Обнаружение шлема и войти. Как вы считаете, это правильный подход? Есть ли какие-нибудь современные инструменты, которые могли бы мне помочь? Спасибо - person Severus Tux; 24.03.2018
comment
@SeverusTux .... Я обновил свой ответ ... Если мое решение полезно и отвечает на ваш вопрос, не забудьте отметить его как правильное - person Jai; 25.03.2018