Хабрахабр

[Из песочницы] Задача классификации глазами школьника: определение наличия автомобиля на парковке по кадрам с камеры видеонаблюдения

Здравствуйте, я школьник 11 классов, интересуюсь программированием, около-IT тематикой.

Публикация может рассматриваться как пример удачной реализации для людей, несведущих в этой области знания, а так же как просьба указать мои ошибки для людей, соответственно, сведущих.
Дано: видео-поток с камеры видеонаблюдения, на котором имеется фрагмент 100x50 пикселей с изображением конкретно парковочного места, на котором может присутствовать или отсутствовать лишь конкретный автомобиль. Пишу данный пост с целью поделиться своим проектом, занявшим 10 часов моей жизни на выходных и выполненным с целью понять возможности современных методов анализа данных.

Изображение с камеры

Изображение парковочного места

Задача: определить наличие или отсутствие автомобиля на парковочном месте.

Получение изображения с камеры

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

dataminer.py

import cv2 as cv
import numpy as np
import time cap = cv.VideoCapture()
r = 0
while r <=100: cap.open('http://**.**.***.***:***/*****CG?container=mjpeg&stream=main') #URL-адрес видеопотока hasFrame, frame = cap.read()#Чтение кадра из потока frame = frame[100:200, 300:750] box = [0,335,100,385] quantframe = frame[box[0]:box[2], box[1]:box[3]]#Сохранение в отдельную переменную части кадра с изображением машины r+=1 cv.imwrite(str(r)+'.png',quantframe) #Сохранение изображения машины в файл print('saved') cap.release() time.sleep(3600) key = cv.waitKey(1) if key & 0xFF == ord('q'): cv.destroyAllWindows() break

Обработка изображения

Я посчитал верным решением обучать нейросеть не на исходных изображениях, а на изображениях с контурами автомобиля, найденными посредством функции cv2.findcontours(...).

Вот код, преобразующий исходное изображение в изображение контуров:

Нахождение контуров

def contoursfinder(image): img = image.copy() srcimg = img.copy() hsv_min = np.array((0, 0, 0), np.uint8) hsv_max = np.array((255, 255, 60), np.uint8) #Поскольку контуры находятся по различиям в цвете между частями картинки, необходимо подобрать параметры, исходя из цветовой гаммы картинки hsv = cv.cvtColor( img, cv.COLOR_BGR2HSV ) thresh = cv.inRange( hsv, hsv_min, hsv_max ) contours, _ = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) img = np.zeros((100,50,3), np.uint8) cv.drawContours(img, contours, -1, (255,255,255), 1, cv.LINE_AA) return cv.cvtColor(img, cv.COLOR_BGR2GRAY)

Результат работы функции:

Скрытый текст

Нейронная сеть

Я использовал библиотеку tensorflow(keras).

Если знающие люди расскажут или подскажут где почитать, почему эта архитектура эффективна или почему какая-та другая будет эффективнее, буду безмерно благодарен.
Модель нейросети: последовательна, состоит из двух плотных скрытых слоев в 256 и 128 нейронов и входного, выходного слоев. Архитектура сети списана с примера с интернетов: для меня неочевидно объяснение, почему именно так.

Код

model = keras.Sequential([ keras.layers.Flatten(input_shape=(100, 50)), keras.layers.Dense(256, activation=tf.nn.relu), keras.layers.Dense(128, activation=tf.nn.relu), keras.layers.Dense(2, activation=tf.nn.softmax)
])
model.compile(optimizer=tf.train.AdamOptimizer(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(trainingimagesarr, trainingimagesarrlabel, epochs=1, callbacks=[tbCallBack])

Перед обучением вся numpy матрица была поделена на 255, дабы давать на вход нейросети числа в диапазоне от 0 до 1.

trainingimagesarr = trainingimagesarr / 255.0
trainingimagesarrlabel = np.array(trainingimagesarrlabel)-1

Теперь я могу вызвав функцию:

def realtest(): cap = cv.VideoCapture() cap.open('http://**.**.***.***:***/*****CG?container=mjpeg&stream=main') hasFrame, frame = cap.read() frame = frame[100:200, 300:750] quantframe = frame[0:100,275:325] quantframe = contoursfinder(quantframe) return model.predict(np.array([quantframe]))[0][1]>0.60

получить данные о наличии автомобиля на стоянке.

Сильно не пинайте, но чуть-чуть 🙂

Спасибо!

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть