Введение
Здравствуйте! В этом руководстве я покажу, как реализовать простое обнаружение объектов с помощью 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
Нравится моя работа? Я пишу на разные темы, если вы хотите увидеть больше, пожалуйста, ставьте лайк и следите за мной.
Также я люблю кофе.