YOLO 공부하기
기본적인 Yolo 사용해보기
기본 Yolo 설치
Yolo V5 설치 YoloV5은 2020년에 새로 개발되었다. 기존 Yolo와 다르게 PyTorch 프레임 워크를 기반으로했따. YoloV4의 상위호환은 아니지만 장점이 있다.
다양한 모델 여러 플렛폼이용 듣등
최근에 YoloV7까지 있는데 천천이 알아보고
! Darknet 및 PyTorch 같은 플렛폼 공부가 필요해 보인다.
1단계 개발 환경 설치
# Tested with torch==1.11.
# Tested with opencv-contrib-python versions [4.5.4.58 to 4.6.0.66].
!pip install torch==1.11 torchvision --user
!pip install opencv-contrib-python==4.6.0.66 --user
2단계 Git코드 가져오기
한글 언어 제외 경로로 설정
!git clone https://github.com/ultralytics/yolov5
%cd yolov5
!pip install -r requirements.txt
!pip install onnx
3단계 모델 다운로드
%cd models
!wget https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5n.pt -nv
!wget https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5s.pt -nv
!wget https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5m.pt -nv
!wget https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5l.pt -nv
!wget https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5x.pt -nv
%cd ..
4단계 ONNX 추출
# The default input size is 640x640.
!python export.py --weights models/yolov5n.pt --include onnx
!python export.py --weights models/yolov5s.pt --include onnx
!python export.py --weights models/yolov5m.pt --include onnx
!python export.py --weights models/yolov5l.pt --include onnx
!python export.py --weights models/yolov5x.pt --include onnx
팁 만약
UnicodeDecodeError: ‘cp949’ codec can’t decode byte 0xf0 in position 9: illegal multibyte sequence 에러 발생시 requirements.txt 열어서 디코딩을 Ansi로 변경
5단계 샘플 이미지 가져오기
https://www.dropbox.com/s/hhx3pbacs7rixid/street.jpg?dl=1 -O street.jpg https://www.dropbox.com/s/wb5nkwuml526bqa/coco.names?dl=1 -O coco.names #객체 저장 이름
라이브러리 호출
import numpy as np
import cv2
import sys
import requests
from os import path
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (15.0,15.0)
plt.rcParams['image.cmap'] = 'gray'
plt.rcParams['axes.titlesize'] = 14
plt.rcParams['axes.labelsize'] = 14
YoloV5는 네모 상자에 예측하기 결과를 애축한다. 모든 예측은 점수에 따라 정해진다 .
# Constants.
INPUT_WIDTH = 640 # Width of network's input image, larger is slower but more accurate
INPUT_HEIGHT = 640 # Height of network's input image, larger is slower but more accurate
SCORE_THRESHOLD = 0.5 # Class score threshold, accepts only if score is above the threshold.
NMS_THRESHOLD = 0.45 # Non-maximum suppression threshold, higher values result in duplicate boxes per object
CONFIDENCE_THRESHOLD = 0.45 # Confidence threshold, high values filter out low confidence detections
# Text parameters.
FONT_FACE = cv2.FONT_HERSHEY_SIMPLEX
FONT_SCALE = 2.5
THICKNESS = 4
# Colors
BLACK = (0,0,0)
BLUE = (255,178,50)
YELLOW = (0,255,255)
RED = (0,0,255)
WHITE = (255,255,255)
전처리 함수
def pre_process(input_image, net):
# Create a 4D blob from a frame.
blob = cv2.dnn.blobFromImage(input_image, 1/255, (INPUT_WIDTH, INPUT_HEIGHT), [0,0,0], 1, crop=False)
# Sets the input to the network.
net.setInput(blob)
# Runs the forward pass to get output of the output layers.
output_layers = net.getUnconnectedOutLayersNames()
outputs = net.forward(output_layers)
# print(outputs[0].shape)
return outputs
결과 출력
def post_process(input_image, outputs):
# Lists to hold respective values while unwrapping.
class_ids = []
confidences = []
boxes = []
# Rows.
rows = outputs[0].shape[1]
image_height, image_width = input_image.shape[:2]
# Resizing factor.
x_factor = image_width / INPUT_WIDTH
y_factor = image_height / INPUT_HEIGHT
# Iterate through 25200 detections.
for r in range(rows):
row = outputs[0][0][r]
confidence = row[4]
# Discard bad detections and continue.
if confidence >= CONFIDENCE_THRESHOLD:
classes_scores = row[5:]
# Get the index of max class score.
class_id = np.argmax(classes_scores)
# Continue if the class score is above threshold.
if (classes_scores[class_id] > SCORE_THRESHOLD):
confidences.append(confidence)
class_ids.append(class_id)
cx, cy, w, h = row[0], row[1], row[2], row[3]
left = int((cx - w/2) * x_factor)
top = int((cy - h/2) * y_factor)
width = int(w * x_factor)
height = int(h * y_factor)
box = np.array([left, top, width, height])
boxes.append(box)
# Perform non maximum suppression to eliminate redundant overlapping boxes with
# lower confidences.
indices = cv2.dnn.NMSBoxes(boxes, confidences, CONFIDENCE_THRESHOLD, NMS_THRESHOLD)
for i in indices:
box = boxes[i]
left = box[0]
top = box[1]
width = box[2]
height = box[3]
cv2.rectangle(input_image, (left, top), (left + width, top + height), BLUE, 4*THICKNESS)
label = "{}:{:.2f}".format(classes[class_ids[i]], confidences[i])
draw_label(input_image, label, left, top)
return input_image
라벨 그리기 함수
def draw_label(input_image, label, left, top):
"""Draw text onto image at location."""
# Get text size.
text_size = cv2.getTextSize(label, FONT_FACE, FONT_SCALE, THICKNESS)
dim, baseline = text_size[0], text_size[1]
# Use text size to create a BLACK rectangle.
cv2.rectangle(input_image, (left, top), (left + dim[0], top + dim[1] + baseline), BLACK, cv2.FILLED);
# Display text inside the rectangle.
cv2.putText(input_image, label, (left, top + dim[1]), FONT_FACE, FONT_SCALE, YELLOW, THICKNESS, cv2.LINE_AA)
효과 넣기 넣기
def put_efficiency(input_img, net):
t, _ = net.getPerfProfile()
label = 'Inference time: %.2f ms' % (t * 1000.0 / cv2.getTickFrequency())
print(label)
cv2.putText(input_img, label, (20, 80), FONT_FACE, FONT_SCALE, RED, THICKNESS, cv2.LINE_AA)
이미지 넣기
frame = cv2.imread('street.jpg')
classesFile = "coco.names"
classes = None
with open(classesFile, 'rt') as f:
classes = f.read().rstrip('\n').split('\n')
plt.imshow(frame[...,::-1]);
결과
YOLOv5 nano
# Load the network.
modelWeights = "models/yolov5n.onnx"
net = cv2.dnn.readNet(modelWeights)
# Process image.
detections = pre_process(frame, net)
img = post_process(frame.copy(), detections)
# Put efficiency information.
put_efficiency(img, net)
plt.imshow(img[...,::-1]);
YOLOv5 small
# Load the network.
modelWeights = "models/yolov5s.onnx"
net = cv2.dnn.readNet(modelWeights)
# Process image.
detections = pre_process(frame, net)
img = post_process(frame.copy(), detections)
# Put efficiency information.
put_efficiency(img, net)
plt.imshow(img[...,::-1]);
YOLOv5 Medium
# Load the network.
modelWeights = "models/yolov5m.onnx"
net = cv2.dnn.readNet(modelWeights)
# Process image.
detections = pre_process(frame, net)
img = post_process(frame.copy(), detections)
# Put efficiency information.
put_efficiency(img, net)
plt.imshow(img[...,::-1]);
YOLOv5 Large
# Load the network.
modelWeights = "models/yolov5l.onnx"
net = cv2.dnn.readNet(modelWeights)
# Process image.
detections = pre_process(frame, net)
img = post_process(frame.copy(), detections)
# Put efficiency information.
put_efficiency(img, net)
plt.imshow(img[...,::-1]);
자료 출처
https://bong-sik.tistory.com/16
https://pysource.com/2019/06/27/yolo-object-detection-using-opencv-with-python/
댓글남기기