Веб-камеры и дверные камеры, такие как Google Nest Cam или любая другая дешевая сетевая камера, отлично подходят для удаленного наблюдения за вашей собственностью.

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

Одним из негативных аспектов, с которым я столкнулся во время тестов с собственными дешевыми сетевыми камерами, было ненадежное оповещение о любом движении.

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

Поднимите руки, если вы столкнулись с таким же поведением встроенной функции обнаружения движения вашей камеры. 😠

Почему обнаружение простого движения не работает?

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

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

Другой аспект заключается в том, что простое обнаружение движения никогда не улавливает истинный смысл конкретной ситуации, наблюдаемой камерой.

Конечно, автоматической программной программе чрезвычайно сложно оценить истинное значение данной ситуации.

Одно улучшение, которое современные камеры безопасности, такие как Google Nest Cam, уже предлагают в дополнение к простому обнаружению движения, заключается в оценке данной сцены, предоставляя вам информацию о том, какие объекты камера обнаруживает в своем записанном виде.

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

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

Как обнаруживать объекты с помощью OpenCV и AI?

Одной из наиболее известных и широко распространенных сред для компьютерного зрения и обнаружения объектов является OpenCV.

Итак, давайте придерживаться OpenCV и попробуем реализовать модель обнаружения, которая способна идентифицировать отдельные объекты на любом заданном изображении, предпочтительно на неподвижном изображении с наших камер безопасности.

Первым шагом является инициализация стандартной модели классификации OpenCV.

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

Скачайте и используйте предварительно обученную модель

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

Давайте загрузим предварительно обученную модель со страницы TensorFlow Object Detection API. Загрузите оба файла весов (.pb) и файл конфигурации (.pbtxt) и поместите их в локальную папку проекта.

Теперь, когда мы успешно загрузили предварительно обученную модель, мы можем инициализировать OpenCV для использования этих предварительно обученных весов, ссылаясь на оба загруженных файла:

config_file = ‘model_config.pbtxt’
frozen_model = ‘graph.pb’
model = cv2.dnn_DetectionModel(frozen_model, config_file)

Модель по-прежнему нуждается в некоторой настройке, чтобы она соответствовала нашему конфигурационному файлу предварительно обученных весов, что означает, что мы должны указать входную ширину и высоту, которые вы можете найти в загруженном файле .pbtxt.

Затем используйте эти значения для дальнейшей инициализации модели, как показано ниже:

model.setInputSize(320, 320)
model.setInputScale(1.0/127.5)
model.setInputMean((127.5,127.5,127.5))
model.setInputSwapRB(True)
model.setInputCrop(False)

После инициализации модели с предварительно обученной моделью она готова классифицировать любой заданный объект изображения. Вызов процедуры обнаружения модели с заданным изображением вернет массив обнаруженных классов (указанных в виде индексов классов) и значение достоверности от 0,0 до 1,0 для каждого обнаруженного объекта. Чтобы найти обнаруженный объект на заданном изображении, вызов обнаружения также возвращает массив ограничивающих рамок, которые можно использовать для отметки обнаруженных объектов на заданном изображении после запуска обнаружения.

ClassIndex, confidence, bbox = model.detect(img, confThreshold=0.2)

Поскольку результат обнаружения просто показывает индекс класса объекта без каких-либо удобочитаемых имен, мы также должны поместить в наш проект файл со всеми удобочитаемыми именами классов (labels.txt). В этом файле вы найдете все 80 удобочитаемых имен классов, которые может идентифицировать наша предварительно обученная модель.

Оберните все в приложение Streamlit Data

Теперь, когда у нас есть готовая модель, мы перенесем процесс обнаружения, а также процесс выбора изображения в удобное приложение Streamlit.

Приложение Streamlit позволит пользователям либо указать URL-адрес для данного изображения, либо загрузить локальное изображение.

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

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

Давайте посмотрим на отдельные части нашего приложения Streamlit, начиная с самой простой части, которая является заголовком нашего приложения:

st.title(‘Camera Object Detection’)

Теперь добавьте поле ввода для указания любого URL-адреса, который ведет к допустимому изображению. Всякий раз, когда значение поля ввода изменяется пользователем, моя вспомогательная функция загрузки изображения вызывается для загрузки данного URL-адреса и создания из него изображения:

url = st.text_input(‘Specify a Picture URL’)
if url is not None and url.startswith(‘http’):
img = download_cam_image(url)
img_file_buffer = None
Now, alternatively offer an image upload widget for users to directly upload their images:
img_file_buffer = st.file_uploader(“Upload an image”, type=[“png”, “jpg”, “jpeg”])
if img_file_buffer is not None:
image = Image.open(img_file_buffer)
img_array = np.asarray(image)
img = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)

Теперь добавляем ползунок, который позволяет пользователям управлять чувствительностью обнаружения:

confidence_threshold = st.slider(
“Confidence threshold”, 0.0, 1.0, DEFAULT_CONFIDENCE_THRESHOLD, 0.05
)

Наконец, мы выведем полученное изображение, а также таблицу обнаруженных объектов с достоверностью обнаружения моделей:

st.image(img)
df = pd.DataFrame(results, columns=([‘Class’, ‘Label’, ‘Confidence’]))
st.dataframe(df)

Полученный пользовательский интерфейс Streamlit будет выглядеть так, как показано на снимке экрана ниже:

Сборка и развертывание с помощью Docker

Как вы можете прочитать в моем предыдущем блоге о Streamlit — Как создавать и публиковать ваши приложения для работы с данными на стероидах?, я пришел к выводу, что создание приложений Streamlit в Docker с самого начала — гораздо лучший выбор.

Итак, все, что нам нужно сделать, это добавить «Dockerfile» вместе с файлом Python «requirements.txt», как показано ниже:

FROM python:3.7
LABEL maintainer=”Wolfgang Beer @wolfgangB33r”
EXPOSE 8501
WORKDIR /app
COPY requirements.txt ./requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD streamlit run src/app.py
streamlit
opencv-python-headless
numpy
requests

Теперь вы можете легко собрать приложение Streamlit, используя следующую команду сборки Docker в консоли:

docker build -f Dockerfile -t cam:latest .

Запустите приложение на локальном компьютере с помощью команды Docker ниже:

docker run -p 8501:8501 cam:latest

Посмотрите записанную демонстрацию получившегося приложения и узнайте, как его можно использовать для обнаружения объектов на любом изображении.

Попробуйте

Если моя статья заставила вас задуматься о том, насколько хорошо обученная модель способна обнаруживать объекты на ваших собственных изображениях, вы можете легко попробовать приложение на Streamlit.io.

Streamlit позволяет пользователям развертывать и совместно использовать свои приложения для работы с данными на собственной платформе времени выполнения. Если вы хотите разместить приложение на своем локальном компьютере или запустить приложение в любой другой среде развертывания Docker, не стесняйтесь клонировать мой репозиторий GitHub ниже.

Получить исходный код

Если вы хотите поиграть с приложением данных Streamlit, представленным в этом блоге, просто зайдите в мой репозиторий GitHub и не стесняйтесь клонировать и модифицировать его.

Резюме

Сетевые камеры повсюду, и они являются удобным способом удаленного наблюдения за вашей собственностью. Автоматизация этих проверок в большинстве случаев терпит неудачу, поскольку простое обнаружение движения плохо работает в реальных сценариях на открытом воздухе.

Использование моделей искусственного интеллекта и глубокого обучения для автоматической идентификации объектов в потоке вашей камеры видеонаблюдения — отличная возможность повысить уровень вашей текущей развернутой камеры.

Используя стандартные обученные модели обнаружения, OpenCV в качестве среды обнаружения, а также Streamlit для пользовательского интерфейса, можно создать и развернуть собственное приложение для обнаружения камер, используя всего 80 строк кода Python. 🚀

Большое спасибо за прочтение, надеюсь, моя статья была вам полезна.

Следуйте за мной на Medium, чтобы быть в курсе будущих статей!