안녕하세요!
YOLO 함수화 및 여러 그림으로 확인해보기 본문
728x90
반응형
https://shinyfood.tistory.com/96
YOLO 설치 및 객체탐지
YOLO란 무엇인가? YOLO(You Only Look Once) 한개의 네트워크(계충, 모델 같은 의미로 칭함.)에서 객체(물체, 사물)을 탐지 탐지된 객체의 영역(바운딩 박스 - 사각형)과 객체의 이름(사람, 고양이 등...)을
shinyfood.tistory.com
해당 글에서 이어집니다.
원본 이미지의 예측한 위치에 바운딩 박스와 레이블(이름), 정확도 출력하기
net = cv2.dnn.readNet("./yolo/config/yolov3.weights",
"./yolo/config/yolov3.cfg")
classes = []
# open(): 파일 열기, r: 읽기, w:쓰기, b가붙으면 바이너리
# f가 곧 open(내용물) 을 뜻하는 변수
with open("./yolo/config/coco.names", "r") as f :
classes = [line.strip() for line in f.readlines()]
# strip() : 왼쪽 공백 제거
# readlines() : 파일 내의 문장들을 행단위로 모두 읽어들이기
해당 폴더에 해당 파일들을 각각 놓고 실행한다.
def predict_yolo(img_path):
# 이미지
img = cv2.imread(img_path)
# BGR을 RGB로 변환하기
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#높이 너비 채널(색상)로 분리
height, width, channels = img.shape
layer_names = net.getLayerNames()
output_layer = [layer_names[i-1] for i in net.getUnconnectedOutLayers()]
# 원본 이미지 데이터를 Blob로 변환하면서, 동시에 정규화(사이즈 통일)하기
blob = cv2.dnn.blobFromImage(
img,
1/256,
(416,416),
(0, 0, 0),
swapRB = True,
crop = False
)
net.setInput(blob)
outs = net.forward(output_layer)
# 인식된 객체(물체)의 인덱스 번호를 담을 변수
class_ids = []
# 인식된 객체의 인식률(정확도)를 담을 변수
confidences = []
# 인식된 객체의 좌표값을 담을 변수
boxes= []
# 출력계층이 반환한 값들을 처리하기 위하여 반복문 사용
for out in outs :
#print(out)
# 인식된 객체에 대한 정보가 담겨 있음.
for detection in out :
# 인식된 객체에 대한 정보 추출하기(클래스=레이어 명칭) 확률 정보
scores = detection[5:]
# print(len(score),score)
"""scores 값이 가장 큰 인덱스 번호 찾기
- 0은 인식 못했다는 의미
- 가장 큰 인덱스 값 : 렝리블 명칭(이름)이 있는 리스트 배열의 인덱스 값을 의미함
"""
class_id = np.argmax(scores)
# print(class_id)
"""score 값이 가장 큰 위치의 인덱스 번호에 해당하는 값은 인식률(정확도)를 의미"""
confidence = scores[class_id]
# print(confidence)
# 정확도(인식률) 50% 이상인 데이터에 대해서 처리하기
if confidence > 0.5 :
# print(f"score : {scores}")
# print(f"class_id : {class_id}")
# print(f"class_id : {classes[class_id]}")
# print(f"confidence : {confidence}")
""" 바운딩 박스의 상태적 x, y 좌표비율 추출하여
- 실제 중심점 길이 좌표(절대 좌표)로 변환하기
"""
# 실제 중심점 x와 y 좌표
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
"""바운딩 박스의 상대적 너비와 높이 비율 추출하기"""
# 실제 너비, 높이로 변환
w = int(detection[2] * width)
h = int(detection[3] * height)
# print(center_x, center_y, w, h)
# 이미지 좌표계는 좌상단이 0,0 그래프 좌표계는 좌하단이 0,0
"""시작점 좌표 계산하기"""
x = int(center_x - w / 2)
y = int(center_y - h / 2)
# print(x, y)
"""실제 x,y, 너비, 높이 값을 리스트로 담기"""
boxes.append([x, y, w, h])
"""객체 인식률(정확도) 실수형 타입으로 담기"""
confidences.append(float(confidence))
"""레이블 명칭(이름) 인덱스 담기"""
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.1, 0.4)
# <폰트스타일 지정>
font = cv2.FONT_HERSHEY_PLAIN
colors = np.random.uniform(0,255, size=(len(boxes), 3))
# 인식된 객체가 있는 경우
if len(indexes) > 0 :
# 무조건 1차원으로 변환
# print(indexes.flatten())
for i in indexes.flatten() :
#x,y,w,h 값 추출하기
x, y, w, h = boxes[i]
# print(x, y, w, h)
# 실제 레이블 명칭(이름) 추출하기
label = str(classes[class_ids[i]])
print(label)
# 인식률(정확도) 추출하기
confidence = str(round(confidences[i], 3))
# print(confidence)
# 바운딩 박스의 색상 추출하기
color = colors[i]
# print(color)
""" 바운딩 박스 그리기
- 마지막 값 2 : 바운딩 박스 선의 굵기(thickness)
"""
cv2.rectangle(img, (x, y), ((x+w), (y+h)), color, 2)
"""인식된 객체의 레이블 명칭(이름)과 정확도 넣기(그리기)"""
cv2.putText(img, label + " " + confidence,
(x, y+20), font, 2, (0,255,0), 2)
plt.axis("off")
plt.imshow(img)
plt.show()
#인식된 객체가 없는 경우
else :
print("I can't detecting!!! No Object!!!")
이제 신나게 이 함수를 부르기만 하면 된다.
"""테스트이미지 모두 가지고오기"""
import glob
import random
#OpenCV 프레임워크 라이브러리
import cv2
paths = glob.glob("./yolo/new_img/*.jpg")
# 랜덤하게 이미지 한개 선택하기
img_path = random.choice(paths)
# 파일 경로의 문자열 내에 역슬래시를 정상적인 슬래시로 변경
img_path = img_path.replace("\\","/")
# 함수 호출하기
print(f"사용된 이미지 : {img_path}")
predict_yolo(img_path)
사용된 이미지 : ./yolo/new_img/1212.jpg
person
person
person
person
person
person
person
person
person
이런식으로 출력된다.
728x90
반응형
'개발일지 > ML(Machine Learning),DL(Deep Learning)' 카테고리의 다른 글
이미지를 이용하여 객체 인식 후 소리내기 (16) | 2024.01.11 |
---|---|
YOLO모델로 영상에서 객체 탐지 (2) | 2024.01.11 |
YOLO 설치 및 객체탐지 (2) | 2024.01.10 |
DNN dropout, callback함수 (2) | 2024.01.09 |
심층훈련망 훈련(DNN) (0) | 2024.01.08 |