NMS : object detectior가 예측한 bounding box중에서 정확한 bounding box를 선택하도록 하는 기법이다.
https://naknaklee.github.io/etc/2021/03/08/NMS/
#1. 필요한 패키지 임포트
import cv2
import numpy as np
#2. 반드시 custom data 안에 라벨링 된 이름으로 써야함
LABELS = ['pineapple','apple']
#3. object detection하려는 사물의 정확도에 대한 확률에 대한 임계치 정보를 적어줍니다.
CONFIDENCE = 0.3 # detection한 사물이 클래스에 해당할 확률
THRESHOLD = 0.3 #NMS(Num Max Suppression) https://naknaklee.github.io/etc/2021/03/08/NMS/
#object detectior가 예측한 bounding box중에서 정확한 bounding box를 선택하도록 하는 기법
#4. cv2에 내장된 readNetFromDarknet함수를 사용
# 다크넷에서 학습시킨 가중치와 환경구성 파일을 불러옴
# 다크넷은 오브젝트 디텍션을 위해 설계된 신경망
net = cv2.dnn.readNetFromDarknet('C:\\object2\\yolov4_custom.cfg','C:\\object2\\yolov4_custom_last.weights')
#5. 위에서 만든 net 신경망을 이용해 object detection 하는 함수(boxing)
def main(img_path):
img = cv2.imread(img_path) # 이미지를 숫자로 불러와서
H, W, _ = img.shape # 세로와 가로 사이즈를 변수로 받음, 색조값은 날려버림
# 이미지를 같은 사이즈(416,416)로 리사이즈하고 정규화 진행
blob = cv2.dnn.blobFromImage(img, scalefactor=1/255., size=(416, 416), swapRB=True)
net.setInput(blob) # 다크넷으로 학습 시킨 신경망에 blob이미지를 넣음
output = net.forward() #이미지를 신경망에 흘려보낸 결과를 output에 담음
boxes, confidences, class_ids = [], [], [] #비어 있는 리스트 3개 선언
#사진에서 학습한 이미지가 있는지 찾아보는 작업
# cnt = 0
#cnt2 = 0
cnt3 = 0
for det in output: #output [:4]:x,y,w,h, [5:]:score 507개의 박스 데이터를 불러옴
# cnt += 1
box = det[:4]
scores = det[5:]
# print(scores) # bounding한 확률 정보 출력
class_id = np.argmax(scores) # [0.960552 0.] 이 입력되면 0이 class_id에 담김
confidence = scores[class_id] # [0.960552 0.]에서 0.960552가 confidence에 담김
if confidence > CONFIDENCE: # confidence가 0.3보다 크면(위에서 선언한 변수)
# cnt2 += 1 # 0.3보다 큰 게 9개이기 때문에, 9개의 정보가 리스트에 담김
cx, cy, w, h = box * np.array([W, H, W, H])
x = cx - (w / 2) # 진짜 사진의 넓이와 높이 740, 515
y = cy - (h / 2) # 507개의 바운딩 박스 중심좌표인 x,y를 알아냄
# box(x,y,w,h)에 이미지의 실제 넓이와 높이를 곱해줌으로써 실제 이미지에서의 박스 x,y 좌표와
# 넓이(w), 높이(h)로 변환함.
boxes.append([int(x), int(y), int(w), int(h)]) # 바운딩 박스 중심좌표 x,y와 w,h를 boxes에 넣음
confidences.append(float(confidence)) # 사과 또는 파인애플일 확률을 confidences에 넣음
class_ids.append(class_id) # class_id에 0 또는 1을 넣음
#Num Max Suppression
idxs = cv2.dnn.NMSBoxes(boxes, confidences, CONFIDENCE, THRESHOLD)
if len(idxs) > 0:
cnt3+=1
for i in idxs.flatten():
x, y, w, h = boxes[i] # boxes 리스트에 9개의 정보(x,y,w,h)중에서 6번째 정보를 x,y,w,h에 넣습니다.
cv2.rectangle(img, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2)
# 네모박스로 바운딩 박스를 그림
# pt1dp 중심좌표를 주고, pt2에는 중심좌표로부터의 넓이와 높이 정보를 줌.
# 박스 색깔은 (0, 0, 255), 선두께는 2
cv2.putText(img, text='%s %.2f %d' % (LABELS[class_ids[i]], confidences[i], w), org=(x, y -10 ), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(0, 0, 255), thickness=2)
# 바운딩 박스 위에 라벨 이름과 확률을 디스플레이 함.
# 중심좌표로부터 -10인 지점 org=(x, y -10 )
cv2.imwrite('c:\\object2\\detection9.png', img)
# print(cnt) 506개의 박스를 신경망이 내보냈다는 것을 확인
# print(cnt2)
print(cnt3)
문제212. 위의 main함수를 다시 실행하는데 박스의 색깔이 파란색이 되게 하시오.
if len(idxs) > 0:
cnt3+=1
for i in idxs.flatten():
x, y, w, h = boxes[i] # boxes 리스트에 9개의 정보(x,y,w,h)중에서 6번째 정보를 x,y,w,h에 넣습니다.
cv2.rectangle(img, pt1=(x, y), pt2=(x + w, y + h), color=(255,0,0), thickness=2)
# 네모박스로 바운딩 박스를 그림
# pt1dp 중심좌표를 주고, pt2에는 중심좌표로부터의 넓이와 높이 정보를 줌.
# 박스 색깔은 (0, 0, 255), 선두께는 2
cv2.putText(img, text='%s %.2f %d' % (LABELS[class_ids[i]], confidences[i], w), org=(x, y -10 ), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(255, 0, 0), thickness=2)
# 바운딩 박스 위에 라벨 이름과 확률을 디스플레이 함.
# 중심좌표로부터 -10인 지점 org=(x, y -10 )
7 고라니와 너구리 디텍션
반응형
'Study > class note' 카테고리의 다른 글
딥러닝 / 고속도로에서 죽는 동물 살리기 GUI 두번째_버튼 두 개 + 사진 저장하지 않고 바로 불러오기 (0) | 2022.05.06 |
---|---|
딥러닝 / 고라니, 너구리 디텍션2 (0) | 2022.05.04 |
딥러닝 / object detection 주피터에서 실행하기 (0) | 2022.05.02 |
딥러닝 / object detection 다른 사진으로 학습시키는 방법 (0) | 2022.05.02 |
딥러닝 / 동영상 object ditection (0) | 2022.05.01 |