Python: распознавание объектов в реальном времени

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


В этой статье мы будем разбирать код программы, в которой используется Deep Learning и OpenCV. Её суть: распознавание объектов в реальном времени.

Содержание статьи:

  • Часть 1: распознавание объектов в реальном времени — работаем с кодом

    • Пишем код для работы с командной строкой

    • Добавляем основные объекты

    • Пишем код для работы с кадрами

    • «Фильтруем» объекты

    • Оставшиеся задачи

  • Часть 2: тестируем распознавание объектов в реальном времени на веб-камере

  • Ссылки

Этот пост разделён на две части. В первой части мы рассмотрим реализацию распознавания объектов в реальном времени, используем deep-learning и OpenCV, чтобы работать с видео потоками и видеофайлами. В этом нам поможет высокоэффективный класс VideoStream, подробнее о нём читайте здесь.

Оттуда мы возьмём Deep Learning, код для обнаружения объекта и код для измерения FPS.

Часть 1: распознавание объектов в реальном времени — работаем с кодом

Чтобы сделать детектор объектов в реальном времени, нам потребуется:

  1. Получить доступ к нашей веб-камере/видео потоку.
  2. Применить распознавание объекта для каждого кадра.

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

Real-time object detection with deep learning and OpenCV

Python

1

2

3

4

5

6

7

8

# import the necessary packages

fromimutils.video importVideoStream

fromimutils.video importFPS

importnumpy asnp

importargparse

importimutils

importtime

importcv2

Мы начали с импортирования библиотек (на строках 2-8). Для этого вам необходим imutils и OpenCV.

Пишем код для работы с командной строкой.

Далее анализируем аргументы командной строки:

Real-time object detection with deep learning and OpenCV

Python

10

11

12

13

14

15

16

17

18

# construct the argument parse and parse the arguments

ap=argparse.ArgumentParser()

ap.add_argument("-p","--prototxt",required=True,

help="path to Caffe 'deploy' prototxt file")

ap.add_argument("-m","--model",required=True,

help="path to Caffe pre-trained model")

ap.add_argument("-c","--confidence",type=float,default=0.2,

help="minimum probability to filter weak detections")

args=vars(ap.parse_args())

  • —prototxt : Путь к prototxt Caffe файлу.
  • —model : Путь к предварительно подготовленной модели.
  • —confidence : Минимальный порог валидности (сходства) для распознавания объекта (значение по умолчанию — 20%).

Добавляем основные объекты.

Затем мы инициализируем список классов и набор цветов:

Python

20

21

22

23

24

25

26

# initialize the list of class labels MobileNet SSD was trained to

# detect, then generate a set of bounding box colors for each class

CLASSES=["background","aeroplane","bicycle","bird","boat",

"bottle","bus","car","cat","chair","cow","diningtable",

"dog","horse","motorbike","person","pottedplant","sheep",

"sofa","train","tvmonitor"]

COLORS=np.random.uniform(0,255,size=(len(CLASSES),3))

На строках 22-26 мы инициализируем метки CLASS и соответствующие случайные цвета.

Теперь загрузим модель и настроим наш видео поток:

Python

28

29

30

31

32

33

34

35

36

37

# load our serialized model from disk

print("[INFO] loading model...")

net=cv2.dnn.readNetFromCaffe(args["prototxt"],args["model"])

# initialize the video stream, allow the cammera sensor to warmup,

# and initialize the FPS counter

print("[INFO] starting video stream...")

vs=VideoStream(src=0).start()

time.sleep(2.0)

fps=FPS().start()

Загружаем нашу сериализованную модель, предоставляя ссылки на prototxt и модели (строка 30) — обратите внимание, насколько это просто в OpenCV.

Затем инициализируем видео поток (это может быть видеофайл или веб-камера). Сначала запускаем VideoStream (строка 35), затем мы ждём, пока камера включится (строка 36), и, наконец, начинаем отсчёт кадров в секунду (строка 37). Классы VideoStream и FPS являются частью пакета imutils.

Пишем код для работы с кадрами.

Теперь проходим по каждому кадру (чтобы увеличить скорость, можно пропускать кадры).

Python

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

# loop over the frames from the video stream

whileTrue:

# grab the frame from the threaded video stream and resize it

# to have a maximum width of 400 pixels

frame=vs.read()

frame=imutils.resize(frame,width=400)

# grab the frame dimensions and convert it to a blob

(h,w)=frame.shape[:2]

blob=cv2.dnn.blobFromImage(cv2.resize(frame,(300,300)),

0.007843,(300,300),127.5)

# pass the blob through the network and obtain the detections and

# predictions

net.setInput(blob)

detections=net.forward()

Первое, что мы делаем — считываем кадр (строка 43) из потока, затем заменяем его размер (строка 44).

Поскольку чуть позже нам понадобится ширина и высота, получим их сейчас (строка 47). Затем следует преобразование кадра в blob с модулем dnn (строки 48 и 49).

Теперь к сложному: мы устанавливаем blob как входные данные в нашу нейросеть (строка 53) и передаём эти данные через net (строка 54), которая обнаруживает наши предметы.

«Фильтруем» объекты.

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

Python

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

# loop over the detections

foriinnp.arange(0,detections.shape[2]):

# extract the confidence (i.e., probability) associated with

# the prediction

confidence=detections[0,0,i,2]

# filter out weak detections by ensuring the `confidence` is

# greater than the minimum confidence

ifconfidence>args["confidence"]:

# extract the index of the class label from the

# `detections`, then compute the (x, y)-coordinates of

# the bounding box for the object

idx=int(detections[0,0,i,1])

box=detections[0,0,i,3:7]*np.array([w,h,w,h])

(startX,startY,endX,endY)=box.astype("int")

# draw the prediction on the frame

label="{}: {:.2f}%".format(CLASSES[idx],

confidence*100)

cv2.rectangle(frame,(startX,startY),(endX,endY),

COLORS[idx],2)

y=startY-15ifstartY-15>15elsestartY+15

cv2.putText(frame,label,(startX,y),

cv2.FONT_HERSHEY_SIMPLEX,0.5,COLORS[idx],2)

Мы начинаем проходить циклами через наши detections, помня, что несколько объектов могут быть восприняты как единое изображение. Мы также делаем проверку на валидность (т.е. вероятность) для каждого обнаружения. Если валидность достаточно велика (т.е. выше заданного порога), отображаем предсказание в терминале, а также рисуем на видео потоке предсказание (обводим объект в цветной прямоугольник и вешаем лейбл).

Давайте разберём по строчкам:

Проходим по detections, получаем значение валидности (строка 60).

Если значение валидности выше заданного порога (строка 64), извлекаем индекс лейбла в классе (строка 68) и высчитываем координаты рамки вокруг обнаруженного объекта (строка 69).

Затем, извлекаем (x;y)-координаты рамки (строка 70), которые будем использовать для отображения прямоугольника и текста.

Делаем текстовый лейбл, содержащую имя из CLASS и значение валидности (строки 73 и 74).

Также, рисуем цветной прямоугольник вокруг объекта, используя цвета класса и раннее извлечённые (x;y)-координаты (строки 75 и 76).

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

Наконец, мы накладываем цветной текст и рамку на кадр, используя значение ‘y’, которое мы только что вычислили (строки 78 и 79).

Оставшиеся задачи:

  1. Отображение кадра
  2. Проверка ключа выхода
  3. Обновление счётчика FPS

Python

80

81

82

83

84

85

86

87

88

89

# show the output frame

cv2.imshow("Frame",frame)

key=cv2.waitKey(1)&0xFF

# if the `q` key was pressed, break from the loop

ifkey==ord("q"):

break

# update the FPS counter

fps.update()

Код вверху довольно очевиден: во-первых, выводим кадр (строка 82). Затем фиксируем нажатие клавиши (строка 83), проверяя, не нажата ли клавиша «q» (quit). Если условие истинно, мы выходим из цикла (строки 86 и 87).

Наконец, обновляем наш счётчик FPS (строка 90).

Если происходит выход из цикла (нажатие клавиши «q» или конец видео потока), у нас есть вещи, о которых следует позаботиться:

91

92

93

94

95

96

97

98

# stop the timer and display FPS information

fps.stop()

print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))

print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

# do a bit of cleanup

cv2.destroyAllWindows()

vs.stop()

При выходе из цикла, останавливаем счётчик FPS (строка 92) и выводим информацию о конечном значении FPS в терминал (строки 93 и 94).

Закрываем окно программы (строка 97), прекращая видео поток (строка 98).

Если вы зашли так далеко, вероятно, вы готовы попробовать программу на своей веб-камере. Чтобы посмотреть, как это делается, перейдём к следующему разделу.

Часть 2: тестируем распознавание объектов в реальном времени на веб-камере

Чтобы увидеть детектор объектов в реальном времени в действии, убедитесь, что вы скачали исходники и предварительно подготовленную Convolutional Neural Network.

Оттуда открываете терминал и выполняете следующие команды:

распознавание объектов в реальном времени

При условии, что OpenCV может получить доступ к вашей веб-камере, вы должны увидеть выходной кадр с любыми обнаруженными объектами. Я привёл примеры результатов в видео ниже:

Заметьте, что распознаватель объектов может обнаруживать не только меня (человека), но и диван, на котором я сижу и стул рядом со мной. И всё это в реальном времени.

Код здесь

Оригинал здесь


Источник: proglib.io

Комментарии: