<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>PythonGuru | Django | Программирование</title><subtitle>Если учить Python, то только у нас🐍

Курсы, книги, интересные статьи по языку программирования Python</subtitle><author><name>PythonGuru | Django | Программирование</name></author><id>https://teletype.in/atom/pythonguru</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/pythonguru?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@pythonguru?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pythonguru"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/pythonguru?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-07T00:15:44.339Z</updated><entry><id>pythonguru:python_object_recognition</id><link rel="alternate" type="text/html" href="https://teletype.in/@pythonguru/python_object_recognition?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pythonguru"></link><title>Python: распознавание объектов в реальном времени</title><published>2021-04-14T08:02:38.722Z</published><updated>2021-04-14T08:02:38.722Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/64/5a/645ae6fc-8403-45b1-8638-f91eed7e8d4d.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/9c/5f/9c5fb934-f07f-4f11-886c-38b542eb9fac.png&quot;&gt;Чтобы сделать детектор объектов в реальном времени, нам потребуется:</summary><content type="html">
  &lt;p&gt;&lt;strong&gt;Чтобы сделать детектор объектов в реальном времени, нам потребуется:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Получить доступ к нашей веб-камере/видео потоку.&lt;/li&gt;
    &lt;li&gt;Применить распознавание объекта для каждого кадра.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/9c/5f/9c5fb934-f07f-4f11-886c-38b542eb9fac.png&quot; width=&quot;2832&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Чтобы посмотреть, как это делается, откройте новый файл, назовите его &lt;strong&gt;real_time_object_detection.py&lt;/strong&gt; и вставьте следующий код:&lt;/p&gt;
  &lt;pre&gt;# import the necessary packages&lt;/pre&gt;
  &lt;pre&gt;from imutils.video import VideoStream&lt;/pre&gt;
  &lt;pre&gt;from imutils.video import FPS&lt;/pre&gt;
  &lt;pre&gt;import numpy as np&lt;/pre&gt;
  &lt;pre&gt;import argparse&lt;/pre&gt;
  &lt;pre&gt;import imutils&lt;/pre&gt;
  &lt;pre&gt;import time&lt;/pre&gt;
  &lt;pre&gt;import cv2&lt;/pre&gt;
  &lt;p&gt;Мы начали с импортирования библиотек (на строках 2-8). Для этого вам необходим &lt;a href=&quot;https://www.pyimagesearch.com/2015/02/02/just-open-sourced-personal-imutils-package-series-opencv-convenience-functions/&quot; target=&quot;_blank&quot;&gt;imutils&lt;/a&gt; и &lt;a href=&quot;https://www.pyimagesearch.com/opencv-tutorials-resources-guides/&quot; target=&quot;_blank&quot;&gt;OpenCV&lt;/a&gt;.&lt;/p&gt;
  &lt;h3&gt;Пишем код для работы с командной строкой.&lt;/h3&gt;
  &lt;p&gt;Далее анализируем аргументы командной строки:&lt;/p&gt;
  &lt;pre&gt;# construct the argument parse and parse the arguments&lt;/pre&gt;
  &lt;pre&gt;ap = argparse.ArgumentParser()&lt;/pre&gt;
  &lt;pre&gt;ap.add_argument(&amp;quot;-p&amp;quot;, &amp;quot;--prototxt&amp;quot;, required=True,&lt;/pre&gt;
  &lt;pre&gt; help=&amp;quot;path to Caffe &amp;#x27;deploy&amp;#x27; prototxt file&amp;quot;)&lt;/pre&gt;
  &lt;pre&gt;ap.add_argument(&amp;quot;-m&amp;quot;, &amp;quot;--model&amp;quot;, required=True,&lt;/pre&gt;
  &lt;pre&gt; help=&amp;quot;path to Caffe pre-trained model&amp;quot;)&lt;/pre&gt;
  &lt;pre&gt;ap.add_argument(&amp;quot;-c&amp;quot;, &amp;quot;--confidence&amp;quot;, type=float, default=0.2,&lt;/pre&gt;
  &lt;pre&gt; help=&amp;quot;minimum probability to filter weak detections&amp;quot;)&lt;/pre&gt;
  &lt;pre&gt;args = vars(ap.parse_args())&lt;/pre&gt;
  &lt;ul&gt;
    &lt;li&gt;--prototxt : Путь к prototxt Caffe файлу.&lt;/li&gt;
    &lt;li&gt;--model : Путь к предварительно подготовленной модели.&lt;/li&gt;
    &lt;li&gt;--confidence : Минимальный порог валидности (сходства) для распознавания объекта (значение по умолчанию - 20%)&lt;strong&gt;.&lt;/strong&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;Добавляем основные объекты.&lt;/h3&gt;
  &lt;p&gt;Затем мы инициализируем список классов и набор цветов:&lt;/p&gt;
  &lt;pre&gt;# initialize the list of class labels MobileNet SSD was trained to&lt;/pre&gt;
  &lt;pre&gt;# detect, then generate a set of bounding box colors for each class&lt;/pre&gt;
  &lt;pre&gt;CLASSES = [&amp;quot;background&amp;quot;, &amp;quot;aeroplane&amp;quot;, &amp;quot;bicycle&amp;quot;, &amp;quot;bird&amp;quot;, &amp;quot;boat&amp;quot;,&lt;/pre&gt;
  &lt;pre&gt; &amp;quot;bottle&amp;quot;, &amp;quot;bus&amp;quot;, &amp;quot;car&amp;quot;, &amp;quot;cat&amp;quot;, &amp;quot;chair&amp;quot;, &amp;quot;cow&amp;quot;, &amp;quot;diningtable&amp;quot;,&lt;/pre&gt;
  &lt;pre&gt; &amp;quot;dog&amp;quot;, &amp;quot;horse&amp;quot;, &amp;quot;motorbike&amp;quot;, &amp;quot;person&amp;quot;, &amp;quot;pottedplant&amp;quot;, &amp;quot;sheep&amp;quot;,&lt;/pre&gt;
  &lt;pre&gt; &amp;quot;sofa&amp;quot;, &amp;quot;train&amp;quot;, &amp;quot;tvmonitor&amp;quot;]&lt;/pre&gt;
  &lt;pre&gt;COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))&lt;/pre&gt;
  &lt;p&gt;На строках 22-26 мы инициализируем метки CLASS и соответствующие случайные цвета.&lt;/p&gt;
  &lt;p&gt;Теперь загрузим модель и настроим наш видео поток:&lt;/p&gt;
  &lt;pre&gt;# load our serialized model from disk&lt;/pre&gt;
  &lt;pre&gt;print(&amp;quot;[INFO] loading model...&amp;quot;)&lt;/pre&gt;
  &lt;pre&gt;net = cv2.dnn.readNetFromCaffe(args[&amp;quot;prototxt&amp;quot;], args[&amp;quot;model&amp;quot;])&lt;/pre&gt;
  &lt;pre&gt;# initialize the video stream, allow the cammera sensor to warmup,&lt;/pre&gt;
  &lt;pre&gt;# and initialize the FPS counter&lt;/pre&gt;
  &lt;pre&gt;print(&amp;quot;[INFO] starting video stream...&amp;quot;)&lt;/pre&gt;
  &lt;pre&gt;vs = VideoStream(src=0).start()&lt;/pre&gt;
  &lt;pre&gt;time.sleep(2.0)&lt;/pre&gt;
  &lt;pre&gt;fps = FPS().start()&lt;/pre&gt;
  &lt;p&gt;Загружаем нашу сериализованную модель, предоставляя ссылки на prototxt и модели (&lt;strong&gt;строка 30&lt;/strong&gt;) - обратите внимание, насколько это просто в OpenCV.&lt;/p&gt;
  &lt;p&gt;Затем инициализируем видео поток (это может быть видеофайл или веб-камера). Сначала запускаем VideoStream (&lt;strong&gt;строка 35&lt;/strong&gt;), затем мы ждём, пока камера включится (&lt;strong&gt;строка 36&lt;/strong&gt;), и, наконец, начинаем отсчёт кадров в секунду (&lt;strong&gt;строка 37&lt;/strong&gt;). Классы VideoStream и FPS являются частью пакета imutils.&lt;/p&gt;
  &lt;h3&gt;Пишем код для работы с кадрами.&lt;/h3&gt;
  &lt;p&gt;Теперь проходим по каждому кадру (чтобы увеличить скорость, можно пропускать кадры).&lt;/p&gt;
  &lt;pre&gt;# loop over the frames from the video stream&lt;/pre&gt;
  &lt;pre&gt;while True:&lt;/pre&gt;
  &lt;pre&gt; # grab the frame from the threaded video stream and resize it&lt;/pre&gt;
  &lt;pre&gt; # to have a maximum width of 400 pixels&lt;/pre&gt;
  &lt;pre&gt; frame = vs.read()&lt;/pre&gt;
  &lt;pre&gt; frame = imutils.resize(frame, width=400)&lt;/pre&gt;
  &lt;pre&gt; # grab the frame dimensions and convert it to a blob&lt;/pre&gt;
  &lt;pre&gt; (h, w) = frame.shape[:2]&lt;/pre&gt;
  &lt;pre&gt; blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)),&lt;/pre&gt;
  &lt;pre&gt;  0.007843, (300, 300), 127.5)&lt;/pre&gt;
  &lt;pre&gt; # pass the blob through the network and obtain the detections and&lt;/pre&gt;
  &lt;pre&gt; # predictions&lt;/pre&gt;
  &lt;pre&gt; net.setInput(blob)&lt;/pre&gt;
  &lt;pre&gt; detections = net.forward()&lt;/pre&gt;
  &lt;p&gt;Первое, что мы делаем - считываем кадр (&lt;strong&gt;строка 43&lt;/strong&gt;) из потока, затем заменяем его размер (&lt;strong&gt;строка 44&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Поскольку чуть позже нам понадобится ширина и высота, получим их сейчас (&lt;strong&gt;строка 47&lt;/strong&gt;). Затем следует преобразование кадра в blob с модулем dnn (&lt;strong&gt;строки 48 и 49&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Теперь к сложному: мы устанавливаем blob как входные данные в нашу нейросеть (&lt;strong&gt;строка 53&lt;/strong&gt;) и передаём эти данные через net (&lt;strong&gt;строка 54&lt;/strong&gt;), которая обнаруживает наши предметы.&lt;/p&gt;
  &lt;h3&gt;&amp;quot;Фильтруем&amp;quot; объекты.&lt;/h3&gt;
  &lt;p&gt;На данный момент, мы обнаружили объекты в видео потоке. Теперь пришло время посмотреть на значения валидности и решить, должны ли мы нарисовать квадрат вокруг объекта и повесить лейбл.&lt;/p&gt;
  &lt;pre&gt; # loop over the detections&lt;/pre&gt;
  &lt;pre&gt; for i in np.arange(0, detections.shape[2]):&lt;/pre&gt;
  &lt;pre&gt;  # extract the confidence (i.e., probability) associated with&lt;/pre&gt;
  &lt;pre&gt;  # the prediction&lt;/pre&gt;
  &lt;pre&gt;  confidence = detections[0, 0, i, 2]&lt;/pre&gt;
  &lt;pre&gt;  # filter out weak detections by ensuring the &amp;#x60;confidence&amp;#x60; is&lt;/pre&gt;
  &lt;pre&gt;  # greater than the minimum confidence&lt;/pre&gt;
  &lt;pre&gt;  if confidence &amp;gt; args[&amp;quot;confidence&amp;quot;]:&lt;/pre&gt;
  &lt;pre&gt;   # extract the index of the class label from the&lt;/pre&gt;
  &lt;pre&gt;   # &amp;#x60;detections&amp;#x60;, then compute the (x, y)-coordinates of&lt;/pre&gt;
  &lt;pre&gt;   # the bounding box for the object&lt;/pre&gt;
  &lt;pre&gt;   idx = int(detections[0, 0, i, 1])&lt;/pre&gt;
  &lt;pre&gt;   box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])&lt;/pre&gt;
  &lt;pre&gt;   (startX, startY, endX, endY) = box.astype(&amp;quot;int&amp;quot;)&lt;/pre&gt;
  &lt;pre&gt;   # draw the prediction on the frame&lt;/pre&gt;
  &lt;pre&gt;   label = &amp;quot;{}: {:.2f}%&amp;quot;.format(CLASSES[idx],&lt;/pre&gt;
  &lt;pre&gt;    confidence * 100)&lt;/pre&gt;
  &lt;pre&gt;   cv2.rectangle(frame, (startX, startY), (endX, endY),&lt;/pre&gt;
  &lt;pre&gt;    COLORS[idx], 2)&lt;/pre&gt;
  &lt;pre&gt;   y = startY - 15 if startY - 15 &amp;gt; 15 else startY + 15&lt;/pre&gt;
  &lt;pre&gt;   cv2.putText(frame, label, (startX, y),&lt;/pre&gt;
  &lt;pre&gt;    cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)&lt;/pre&gt;
  &lt;p&gt;Мы начинаем проходить циклами через наши &lt;em&gt;detections,&lt;/em&gt; помня, что несколько объектов могут быть восприняты как единое изображение. Мы также делаем проверку на валидность (т.е. вероятность) для каждого обнаружения. Если валидность достаточно велика (т.е. выше заданного порога), отображаем предсказание в терминале, а также рисуем на видео потоке предсказание (обводим объект в цветной прямоугольник и вешаем лейбл).&lt;/p&gt;
  &lt;p&gt;Давайте разберём по строчкам:&lt;/p&gt;
  &lt;p&gt;Проходим по &lt;em&gt;detections&lt;/em&gt;, получаем значение валидности (&lt;strong&gt;строка 60&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Если значение валидности выше заданного порога (&lt;strong&gt;строка 64&lt;/strong&gt;), извлекаем индекс лейбла в классе (&lt;strong&gt;строка 68&lt;/strong&gt;) и высчитываем координаты рамки вокруг обнаруженного объекта (&lt;strong&gt;строка 69&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Затем, извлекаем (x;y)-координаты рамки (&lt;strong&gt;строка 70&lt;/strong&gt;), которые будем использовать для отображения прямоугольника и текста.&lt;/p&gt;
  &lt;p&gt;Делаем текстовый лейбл, содержащую имя из CLASS и значение валидности (&lt;strong&gt;строки 73 и 74&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Также, рисуем цветной прямоугольник вокруг объекта, используя цвета класса и раннее извлечённые (x;y)-координаты (&lt;strong&gt;строки 75 и 76&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;В целом, нужно, чтобы лейбл располагался над цветным прямоугольником, однако, может возникнуть такая ситуация, что сверху будет недостаточно места, поэтому в таких случаях выводим лейбл под верхней стороной прямоугольника (&lt;strong&gt;строка 77&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Наконец, мы накладываем цветной текст и рамку на кадр, используя значение &amp;#x27;y&amp;#x27;, которое мы только что вычислили (&lt;strong&gt;строки 78 и 79&lt;/strong&gt;).&lt;/p&gt;
  &lt;h3&gt;Оставшиеся задачи&lt;strong&gt;:&lt;/strong&gt;&lt;/h3&gt;
  &lt;ol&gt;
    &lt;li&gt;Отображение кадра&lt;/li&gt;
    &lt;li&gt;Проверка ключа выхода&lt;/li&gt;
    &lt;li&gt;Обновление счётчика FPS&lt;/li&gt;
  &lt;/ol&gt;
  &lt;pre&gt;# show the output frame&lt;/pre&gt;
  &lt;pre&gt; cv2.imshow(&amp;quot;Frame&amp;quot;, frame)&lt;/pre&gt;
  &lt;pre&gt; key = cv2.waitKey(1) &amp;amp; 0xFF&lt;/pre&gt;
  &lt;pre&gt; # if the &amp;#x60;q&amp;#x60; key was pressed, break from the loop&lt;/pre&gt;
  &lt;pre&gt; if key == ord(&amp;quot;q&amp;quot;):&lt;/pre&gt;
  &lt;pre&gt;  break&lt;/pre&gt;
  &lt;pre&gt; # update the FPS counter&lt;/pre&gt;
  &lt;pre&gt; fps.update()&lt;/pre&gt;
  &lt;p&gt;Код вверху довольно очевиден: во-первых, выводим кадр (&lt;strong&gt;строка 82&lt;/strong&gt;). Затем фиксируем нажатие клавиши (&lt;strong&gt;строка 83&lt;/strong&gt;), проверяя, не нажата ли клавиша &amp;quot;q&amp;quot; (quit). Если условие истинно, мы выходим из цикла (&lt;strong&gt;строки 86 и 87&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Наконец, обновляем наш счётчик FPS (&lt;strong&gt;строка 90&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Если происходит выход из цикла (нажатие клавиши &amp;quot;q&amp;quot; или конец видео потока), у нас есть вещи, о которых следует позаботиться:&lt;/p&gt;
  &lt;pre&gt;# stop the timer and display FPS information&lt;/pre&gt;
  &lt;pre&gt;fps.stop()&lt;/pre&gt;
  &lt;pre&gt;print(&amp;quot;[INFO] elapsed time: {:.2f}&amp;quot;.format(fps.elapsed()))&lt;/pre&gt;
  &lt;pre&gt;print(&amp;quot;[INFO] approx. FPS: {:.2f}&amp;quot;.format(fps.fps()))&lt;/pre&gt;
  &lt;pre&gt;# do a bit of cleanup&lt;/pre&gt;
  &lt;pre&gt;cv2.destroyAllWindows()&lt;/pre&gt;
  &lt;pre&gt;vs.stop()&lt;/pre&gt;
  &lt;p&gt;При выходе из цикла, останавливаем счётчик FPS (&lt;strong&gt;строка 92&lt;/strong&gt;) и выводим информацию о конечном значении FPS в терминал (&lt;strong&gt;строки 93 и 94&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Закрываем окно программы (&lt;strong&gt;строка 97&lt;/strong&gt;), прекращая видео поток (&lt;strong&gt;строка 98&lt;/strong&gt;).&lt;/p&gt;
  &lt;p&gt;Если вы зашли так далеко, вероятно, вы готовы попробовать программу на своей веб-камере. Чтобы посмотреть, как это делается, перейдём к следующему разделу.&lt;/p&gt;
  &lt;h3&gt;Часть 2: тестируем распознавание объектов в реальном времени на веб-камере&lt;/h3&gt;
  &lt;p&gt;Чтобы увидеть детектор объектов в реальном времени в действии, убедитесь, что вы скачали исходники и предварительно подготовленную Convolutional Neural Network.&lt;/p&gt;
  &lt;p&gt;Оттуда открываете терминал и выполняете следующие команды:&lt;/p&gt;
  &lt;pre&gt;$ python real_time_object_detection.py \&lt;/pre&gt;
  &lt;pre&gt; --prototxt MobileNetSSD_deploy.prototxt.txt \&lt;/pre&gt;
  &lt;pre&gt; --model MobileNetSSD_deploy.caffemodel&lt;/pre&gt;
  &lt;pre&gt;[INFO] loading model...&lt;/pre&gt;
  &lt;pre&gt;[INFO] starting video stream...&lt;/pre&gt;
  &lt;pre&gt;[INFO] elapsed time: 55.07&lt;/pre&gt;
  &lt;pre&gt;[INFO] approx. FPS: 6.54
&lt;/pre&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/hMFx1TXjAJc?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;p&gt;Еще больше интересных статей на нашем сайте &lt;a href=&quot;https://cyberguru.tech&quot; target=&quot;_blank&quot;&gt;https://cyberguru.tech&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Вот некоторые из них:&lt;/p&gt;
  &lt;p&gt;- &lt;a href=&quot;https://cyberguru.tech/%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/python-numbers&quot; target=&quot;_blank&quot;&gt;Числа в Python&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;-&lt;a href=&quot;https://cyberguru.tech/%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/python-install&quot; target=&quot;_blank&quot;&gt; Установка Python 3&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Полезно? Подпишитесь на наш канал в Telegram &lt;a href=&quot;https://t.me/gurupython&quot; target=&quot;_blank&quot;&gt;https://t.me/gurupython&lt;/a&gt; &lt;/p&gt;
  &lt;p&gt;Обсудить код можно в нашем чате &lt;a href=&quot;https://t.me/pythonguruchat&quot; target=&quot;_blank&quot;&gt;https://t.me/pythonguruchat&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

</content></entry></feed>