728x90
반응형
YOLO 코드 분석
import sys
import numpy as np
import cv2
# Darknet model & config
model = 'yolov3.weights'
config = 'yolov3.cfg'
class_labels = 'coco.names'
confThreshold = 0.5
nmsThreshold = 0.4
# Test image file
img_files = ['dog.jpg', 'person.jpg', 'kite.jpg', 'car2.jpg',
'dog_1.jpg','car.jpg', 'person1.jpg','person2.jpg' ]
# Network creation ( readNet을 사용해서 파일링 )
net = cv2.dnn.readNet(model, config)
if net.empty():
print('Net open failed!')
sys.exit()
# class_labels '\n\' 기준으로 모두 string으로 list -> classes
classes = []
with open(class_labels, 'rt') as f:
classes = f.read().rstrip('\n').split('\n')
# calss_labels 80EA random RGB 배열을 생성
colors = np.random.uniform(0, 255, size=(len(classes), 3))
# out layer names 받아오기
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
#getUnconnectedOutLayers() 에 포함된 layers 의 이름을 불러온다
# 위 2줄의 코드를 실행하게 되면 output_layers = ['yolo_82', 'yolo_94', 'yolo_106'] 문자열이 저장이 됨
# 출력을 3번해서 조합해서 한개의 결과물로 출력
# 실행
# for 문으로 이미지를 한장씩 불러옴
for f in img_files:
img = cv2.imread(f)
if img is None:
continue
# blob(Binary Large Object) 생성 & 추론
# Size : ( 320, 320 ) / ( 416, 416 ) / ( 608, 608)
# resize : 320, 320
# Scale : 0.00392 ( 1/ 255 ) @ 0 ~ 1 사이로 노멀라이즈 스케일링 팩터를 줘야 함 (1/255)
# Mean : [0,0,0]
# RGB : swapRB=True # opencv는 BGR format.. flag 를 swapRB=True 로 설정
blob = cv2.dnn.blobFromImage(img, 1/255., (320, 320), swapRB=True)
net.setInput(blob)
outs = net.forward(output_layers)
#forward(문자열리스트) 에 해당하는 아웃풋을 outs 에 넣어준다
# outs는 3( 82, 94, 106 번째 layer)개의 ndarray 리스트.
# outs[0].shape=(507, 85), 13*13*3=507
# outs[1].shape=(2028, 85), 26*26*3=2028
# outs[2].shape=(8112, 85), 52*52*3=8112
h, w = img.shape[:2]
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
# detection: 4(bounding box) + 1(objectness_score) + 80(class confidence)
scores = detection[5:]
# scores : 5번째 값 이상인 것 / 80개 중에서
class_id = np.argmax(scores)
# np.argmax(scores) 80개 중에서 최대값이 있는 위치를 class_id 에 넣어준다
confidence = scores[class_id]
# 그 위치에서 confidence 값을 확인
if confidence > confThreshold: # 0.5 이상인 것만 bounding box 취합
# 바운딩 박스 중심 좌표 & 박스 크기
# 노멀라이즈 되어 있어서 w,h 를 곱해줘야 실제 영상에 맞는 좌표가 제대로 계산이 됨
cx = int(detection[0] * w) # center X
cy = int(detection[1] * h) # center Y
bw = int(detection[2] * w) # box W
bh = int(detection[3] * h) # box H
# 바운딩 박스 좌상단 좌표
sx = int(cx - bw / 2)
sy = int(cy - bh / 2)
boxes.append([sx, sy, bw, bh]) # confidence 값이 0.5보다 큰 bounding box를 모두 boxes에 list형태로 추가
confidences.append(float(confidence)) # confidences list 도 함께 기록
class_ids.append(int(class_id)) # class_ids list 도 함께 기록
# 비최대 억제
indices = cv2.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
# nmsThreshold = 0.4 이상으로 겹치게 되는 박스들을 중에서
# confThreshold = 0.5 보다 큰 것들 중에서 가장 큰 confidence 를 갖는 하나만 골라서 indices 에 넣어준다
for i in indices: # 여기서 indices 는 2차원 행렬로 생성 ( ex n행 1열 로 생성)
i = i[0] #i[0] 째를 다시 i 로 casting
sx, sy, bw, bh = boxes[i] # box 정보를 다시 불러온다 , confidence 값이 가장 높은 'i' 외의 다른 box 들은 모두 무시되었음
label = f'{classes[class_ids[i]]}: {confidences[i]:.2}' #class_ids에 해당하는 문자열을 받아온다
color = colors[class_ids[i]]
cv2.rectangle(img, (sx, sy, bw, bh), color, 2)
cv2.putText(img, label, (sx, sy - 10), # 107 줄의 label 을 putText 로 출력
cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2, cv2.LINE_AA)
t, _ = net.getPerfProfile() #net.getPerfProfile() 인퍼런스 시킬때 시간을 계산하고 받아오는 함수
label = 'Inference time: %.2f ms' % (t * 1000.0 / cv2.getTickFrequency())
cv2.putText(img, label, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0, 0, 255), 1, cv2.LINE_AA) # 좌측 상단에 inference time 출력
cv2.imshow('img', img,) # img 출력
cv2.waitKey()
cv2.destroyAllWindows()
video 도 돌려보고싶은데
에러가 자꾸 난다
yolov3_tf2.models
yolov3_tf2.utils 이게 자꾸 에러가 남 ㅠ
from absl import app, flags, logging
from absl.flags import FLAGS
import numpy as np
from yolov3_tf2.models import YoloV3, YoloV3Tiny
from yolov3_tf2.utils import load_darknet_weights
import tensorflow as tf
flags.DEFINE_string('weights', './data/yolov3.weights', 'path to weights file')
flags.DEFINE_string('output', './checkpoints/yolov3.tf', 'path to output')
flags.DEFINE_boolean('tiny', False, 'yolov3 or yolov3-tiny')
flags.DEFINE_integer('num_classes', 80, 'number of classes in the model')
def main(_argv):
physical_devices = tf.config.experimental.list_physical_devices('GPU')
if len(physical_devices) > 0:
tf.config.experimental.set_memory_growth(physical_devices[0], True)
if FLAGS.tiny:
yolo = YoloV3Tiny(classes=FLAGS.num_classes)
else:
yolo = YoloV3(classes=FLAGS.num_classes)
yolo.summary()
logging.info('model created')
load_darknet_weights(yolo, FLAGS.weights, FLAGS.tiny)
logging.info('weights loaded')
img = np.random.random((1, 320, 320, 3)).astype(np.float32)
output = yolo(img)
logging.info('sanity check passed')
yolo.save_weights(FLAGS.output)
logging.info('weights saved')
if __name__ == '__main__':
try:
app.run(main)
except SystemExit:
pass
# python detect_video.py --video 0
728x90
반응형
'etc > FastCampus 챌린지' 카테고리의 다른 글
[패스트캠퍼스 수강 후기] 컴퓨터비전인강 100% 환급 챌린지 30 회차 (0) | 2020.11.17 |
---|---|
[패스트캠퍼스 수강 후기] 컴퓨터비전인강 100% 환급 챌린지 29 회차 (0) | 2020.11.16 |
[패스트캠퍼스 수강 후기] 컴퓨터비전인강 100% 환급 챌린지 26 회차 (0) | 2020.11.13 |
[패스트캠퍼스 수강 후기] 컴퓨터비전인강 100% 환급 챌린지 25 회차 (0) | 2020.11.12 |
[패스트캠퍼스 수강 후기] 컴퓨터비전인강 100% 환급 챌린지 24 회차 (0) | 2020.11.11 |