Обнаружение объектов с помощью OpenCV и Python

Введение

Здравствуйте! В этом руководстве я покажу, как реализовать простое обнаружение объектов с помощью Python и OpenCV. ?.

Для этого урока потребуются веса и т.д. из следующего поста:
https://dev.to/ethand91/setting-up-yolo-with-darknet-1ehm


Настройка проекта

Сначала нам нужно добавить следующие файлы в каталог «weights»:

  • coco.names
  • yolov3.cfg
  • yolov3.weights

Также нам нужно инициализировать виртуальное окружение:

python3 -m venv env
source env/bin/activate

mkdir weights
cp [darknet directory]/cfg/coco.names weights/
cp [darknet directory]/cfg/yolov3.cfg weights/
cp [darknet directory]/yolov3.weights
Войти в полноэкранный режим Выйти из полноэкранного режима

Установка зависимостей

Далее нам нужно установить зависимости, необходимые для примера, создайте файл «requirements.txt» и добавьте в него следующее:

# requirements.txt
opencv-python
argparse
numpy
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем установите через:

pip install -r requirements.txt
Войти в полноэкранный режим Выйти из полноэкранного режима

Написание исходного кода

Сначала нам нужно импортировать необходимые модули:


import numpy as np
import argparse
import cv2
Войти в полноэкранный режим Выйти из полноэкранного режима

Далее объявим необходимые переменные и инициализируем сетевую модель:

LABELS_FILE = "weights/coco.names"
CONFIG_FILE = "weights/yolov3.cfg"
WEIGHTS_FILE = "weights/yolov3.weights"
CONFIDENCE_THRESHOLD = 0.3

LABELS = open(LABELS_FILE).read().strip().split("n")

np.random.seed(4)
COLORS = np.random.randint(0, 255, size = (len(LABELS), 3), dtype = "uint8")

net = cv2.dnn.readNetFromDarknet(CONFIG_FILE, WEIGHTS_FILE)
Войти в полноэкранный режим Выйти из полноэкранного режима

Следующая функция перебирает все обнаруженные объекты, найденные на изображении, проверяет, превышает ли доверие минимальный порог, и если да, то добавляет ящик в массив boxes вместе с координатами, по которым он был обнаружен.

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

Наконец, измененное изображение отображается на экране.

def drawBoxes (image, layerOutputs, H, W):
  boxes = []
  confidences = []
  classIDs = []

  for output in layerOutputs:
    for detection in output:
      scores = detection[5:]
      classID = np.argmax(scores)
      confidence = scores[classID]

      if confidence > CONFIDENCE_THRESHOLD:
        box = detection[0:4] * np.array([W, H, W, H])
        (centerX, centerY, width, height) = box.astype("int")

        x = int(centerX - (width / 2))
        y = int(centerY - (height / 2))

        boxes.append([x, y, int(width), int(height)])
        confidences.append(float(confidence))
        classIDs.append(classID)

  idxs = cv2.dnn.NMSBoxes(boxes, confidences, CONFIDENCE_THRESHOLD, CONFIDENCE_THRESHOLD)

  # Ensure at least one detection exists
  if len(idxs) > 0:
    for i in idxs.flatten():
      (x, y) = (boxes[i][0], boxes[i][1])
      (w, h) = (boxes[i][2], boxes[i][3])

      color = [int(c) for c in COLORS[classIDs[i]]]

      cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
      text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])
      cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)

  # Display the image
  cv2.imshow("output", image)
Вход в полноэкранный режим Выход из полноэкранного режима

Следующая функция считывает файл изображения по указанному пути, создает блоб из изображения и устанавливает входные данные сети.

Затем мы получаем выходы слоев и передаем необходимые переменные в функцию, которая была определена выше.

def detectObjects (imagePath):
  image = cv2.imread(imagePath)
  (H, W) = image.shape[:2]

  ln = net.getLayerNames()
  ln = [ln[i - 1] for i in net.getUnconnectedOutLayers()]

  blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB = True, crop = False)
  net.setInput(blob)
  layerOutputs = net.forward(ln)
  drawBoxes(image, layerOutputs, H, W)
Вход в полноэкранный режим Выход из полноэкранного режима

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

После этого мы завершаем работу, уничтожая окно.

if __name__ == "__main__":
  ap = argparse.ArgumentParser()
  ap.add_argument("-i", "--image", required = True, help = "Path to input file")

  args = vars(ap.parse_args())
  detectObjects(args["image"])

  cv2.waitKey(0)
  cv2.destroyAllWindows()
Вход в полноэкранный режим Выход из полноэкранного режима

Выполнение программы

Программа может быть выполнена следующей командой:

python main.py -i horses.png
Войти в полноэкранный режим Выйти из полноэкранного режима

Если все прошло успешно, вы должны увидеть следующее изображение:

Не стесняйтесь пробовать с различными изображениями. ?


Заключение

В этом посте я показал, как реализовать простое обнаружение объектов с помощью python и openCV.

Исходный код этого руководства можно найти на Github:
https://github.com/ethand91/object-detect


Нравится моя работа? Я пишу на разные темы, если вы хотите увидеть больше, пожалуйста, ставьте лайк и следите за мной.
Также я люблю кофе.

Оставьте комментарий

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