<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>PythonGuru | Django | Программирование</title><generator>teletype.in</generator><description><![CDATA[Если учить Python, то только у нас🐍

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

]]></content:encoded></item></channel></rss>