본문 바로가기

Study/class note

딥러닝 / object detection 주피터에서 실행하기2, 고라니와 너구리 디텍션

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  고라니와 너구리 디텍션

Object_Detection3_고라니_너구리_.ipynb
1.47MB

반응형