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

Так как сжатые строки и ограниченные ресурсы коррелируют между собой, то нужно разобраться с ними в первую очередь. Эти проблемы подтолкнули нас к решению отказаться от обработки потокового видео, решили обрабатывать не все кадры, а только 1 кадр с дельтой по времени в 4 секунды (цифра выбрана исходя из опыта проб и ошибок). Для получения скриншотов наша задача оказалась очень подходящей, т.к. можно их скачивать через url адрес с помощью библиотеки python request.

Отсутствие обучающей выборки заставило нас обратить внимание на размеченные датасеты MS COCO. На просторах интернета нашли open source решения PythonAPI (pycocotools) – библиотека для использования СOCO API на языке python с предобученными весами на Mask R-CNN. Найденная информация подтолкнула нас к использованию именно этой реализации нейросети на Python 3, Keras и TensorFlow, генерирующую ограничительные рамки и маски сегментации для каждого из экземпляров объектов в изображении. Он основан на функциональной пирамидальной сети (FPN) и магистрали ResNet101.

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

Для установки пакета запустите из командной строки pip install. То же самое нужно проделать с Mask R-CNN (github). Пакеты необходимо именно клонировать из этого git репозитория, чтобы избежать ошибок. Еще одним важным условием успешного инсталлирования библиотеки является наличие установленного и прописанного в системные пути компонента Visual C ++ 2015 Build Tools (файл visualcppbuildtools_full.exe).

При запуске pip install pycocotools у нас возникла проблема:

Исправить ошибку получилось после внесения изменений в файл setup.py – библиотеки — там нужно было заменить строку

extra_compile_args=[‘-Wno-cpp’, ‘-Wno-unused-function’, ‘-std=c99’] на extra_compile_args={‘gcc’: [‘/Qstd=c99’]}

После данных манипуляций ошибок больше не возникало, и библиотека pycocotools установилась успешно.

Чтобы воспользоваться предобученными весами на датасете COCO вам нужно будет скачать файл mask_rcnn_coco.h5 и положить его в клонированную директорию Mask R-CNN. В папке samples есть файл demo, именно его мы и использовали как baseline для своего решения. При импорте библиотек, у вас может возникнуть ошибка.

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

Далее используем модель, обученную на наборе данных MS-COCO и загружаем уже существующие веса.

maskrcnn_model = modellib.MaskRCNN(mode=»inference», model_dir=MODEL_FILE, config=config)
maskrcnn_model.load_weights(COCO_MODEL, by_name=True)

Модель классифицирует объекты и возвращает id классов, представляющие собой целочисленные значения, идентифицирующие каждый класс. Некоторые наборы данных присваиваются целочисленные значения в свои классы, а некоторые нет. Чтобы получить список имен классов, необходимо загрузить набор данных, а затем использовать свойство class_names.

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

from PIL import Image
arr = os.listdir(‘images/1-10’)
count_all=0
count_sotr = 0
z=0
res = pd.DataFrame(columns=[‘path’,’frame’,’people_all’,’sotr’,’clients’,
‘max_sotr’])
for v in arr:
image_list = os.listdir(‘images/’+v)
for i in image_list:
try
image = Image.open(‘images/’+v+’/’+i)
area = (1185,297,1435,635) # область анализа
cropped_img = image.crop(area)
results = maskrcnn_model.detect([np.array(cropped_img)], verbose=False)
r = results[0]
count_all =0
count_sotr=0
for k in (range(len(r[‘rois’]))):
if r[‘class_ids’][k] == 1:

if r[‘rois’][k][0] > 233 :
count_sotr = count_sotr + 1
count_all =count_all +1
except:
print (‘cannot open’)
cl = count_all-count_sotr
print (v,i,count_all,count_sotr)
new_row = [v,i,count_all,count_sotr,cl,0]
res.loc[z] = new_row
z = z +1
res[‘max_sotr’] = res.groupby([‘path’])[‘sotr’].transform(‘max’)
writer = pd.ExcelWriter(‘images/result.xlsx’)
res.to_excel(writer, ‘Sheet1’,index=False)
writer.save()

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

my_image = skimage.io.imread(«foto.jpg»)
result = maskrcnn_model.detect([my_image], verbose=1)
detect_results = result[0]
visualize.display_instances(my_image, detect_results[‘rois’], detect_results[‘masks’], detect_results[‘class_ids’],
class_names, detect_results[‘scores’])

В результате распознавания получим вот такую картинку:

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

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

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


Написать