๐Ÿ“Œ ๋ชฉ์ฐจ

1. YOLO v3๋กœ ์ •์ง€์˜์ƒ์—์„œ Object Detectionํ•˜๊ธฐ
2. YOLO v3๋กœ ๋น„๋””์˜ค์—์„œ Object Detectionํ•˜๊ธฐ(๋žฉํƒ‘ ์บ ์‚ฌ์šฉ)

 

0.  ํŒŒ์ผ์ค€๋น„ ๋ฐ YOLO v3 ๊ณตํ†ต์ฝ”๋“œ

๋จผ์ € ์ž์‹ ์˜ ๋กœ์ปฌ ํด๋”์— ๋‹ค์Œ 3๊ฐœ์˜ ํŒŒ์ผ์ด ์žˆ์–ด์•ผํ•œ๋‹ค.
โˆ™ 'coco_names.txt' (์ด ํŒŒ์ผ์€ 1~80ํ–‰๊นŒ์ง€ ๋ณต์‚ฌํ›„ txtํŒŒ์ผ์„ ์ƒ์„ฑํ•ด ๋ถ™์—ฌ๋„ฃ๋Š”๋‹ค.)
โˆ™ 'yolov3.weights'
โˆ™ 'yolov3.cfg'


์ดํ›„ ์•„๋ž˜ ์ฝ”๋“œ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ณด๊ฒ ๋‹ค.
- 5~13ํ–‰: YOLO ๋ชจ๋ธ ๊ตฌ์„ฑํ•จ์ˆ˜
- 15~38ํ–‰: YOLO๋ชจ๋ธ๋กœ img์˜์ƒ์—์„œ ๋ฌผ์ฒดํƒ์ง€ ํ›„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
def construct_yolo_v3():
    f=open('coco_names.txt', 'r')
    class_names=[line.strip() for line in f.readlines()]

    model=cv.dnn.readNet('yolov3.weights','yolov3.cfg')
    layer_names=model.getLayerNames()
    out_layers=[layer_names[i-1] for i in model.getUnconnectedOutLayers()]
    
    return model,out_layers,class_names

def yolo_detect(img,yolo_model,out_layers):
    height,width=img.shape[0],img.shape[1]
    test_img=cv.dnn.blobFromImage(img,1.0/256,(448,448),(0,0,0),swapRB=True)
    
    yolo_model.setInput(test_img)
    output3=yolo_model.forward(out_layers)
    
    box,conf,id=[],[],[]		# ๋ฐ•์Šค, ์‹ ๋ขฐ๋„, ํด๋ž˜์Šค ๋ฒˆํ˜ธ
    for output in output3:
        for vec85 in output:
            scores=vec85[5:]
            class_id=np.argmax(scores)
            confidence=scores[class_id]
            if confidence>0.5:	# ์‹ ๋ขฐ๋„๊ฐ€ 50% ์ด์ƒ์ธ ๊ฒฝ์šฐ๋งŒ ์ทจํ•จ
                centerx,centery=int(vec85[0]*width),int(vec85[1]*height)
                w,h=int(vec85[2]*width),int(vec85[3]*height)
                x,y=int(centerx-w/2),int(centery-h/2)
                box.append([x,y,x+w,y+h])
                conf.append(float(confidence))
                id.append(class_id)
            
    ind=cv.dnn.NMSBoxes(box,conf,0.5,0.4)
    objects=[box[i]+[conf[i]]+[id[i]] for i in range(len(box)) if i in ind]
    return objects

model,out_layers,class_names=construct_yolo_v3()		# YOLO ๋ชจ๋ธ ์ƒ์„ฑ
colors=np.random.uniform(0,255,size=(len(class_names),3))	# ํด๋ž˜์Šค๋งˆ๋‹ค ์ƒ‰๊น”โ€‹

 

05~13ํ–‰์˜ construct_yolo_v3 ํ•จ์ˆ˜๋ฅผ ์‚ดํŽด๋ณด์ž.
โˆ™ 06~07ํ–‰์€ COCO ๋ฐ์ดํ„ฐ์…‹์˜ ํด๋ž˜์Šค์ด๋ฆ„์„ ๋‹ด๊ณ  ์žˆ๋Š” coco_names. txt ํŒŒ์ผ์—์„œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ฝ์–ด class_names์— ์ €์žฅํ•œ๋‹ค.

โˆ™ 09ํ–‰์€ YOLO v3 ๋ชจ๋ธ ์ •๋ณด๋ฅผ ํŒŒ์ผ์—์„œ ์ฝ์–ด yolo_model ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.

yolov3.weights ํŒŒ์ผ์—์„œ๋Š” ์‹ ๊ฒฝ๋ง์˜ ๊ฐ€์ค‘์น˜ ์ •๋ณด๋ฅผ ์ฝ์–ด์˜ค๊ณ  yolov3.cfg ํŒŒ์ผ์—์„œ๋Š” ์‹ ๊ฒฝ๋ง์˜ ๊ตฌ์กฐ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

โˆ™ 10~11ํ–‰์€ getUnconnectedOutLayers ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ yolo 82, yolo 94, yolo_106 ์ธต์„ ์•Œ์•„๋‚ด์–ด out_layers ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.

โˆ™ 13ํ–‰์€ ๋ชจ๋ธ, ์ธต, ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋‹ด์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.


15~38ํ–‰์˜ yolo_detect ํ•จ์ˆ˜๋ฅผ ์‚ดํŽด๋ณด์ž.
โˆ™ 16ํ–‰์€ ์›๋ณธ ์˜์ƒ์ธ img์˜ ๋†’์ด์™€ ๋„ˆ๋น„ ์ •๋ณด๋ฅผ height์™€ width์— ์ €์žฅํ•œ๋‹ค.

โˆ™ 17ํ–‰์€ OpenCV์˜ blobFromImage ํ•จ์ˆ˜๋กœ ์˜์ƒ์„ YOLO์— ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด test_img์— ์ €์žฅํ•œ๋‹ค.
์ด ํ•จ์ˆ˜๋Š” [0,255] ๋ฒ”์œ„์˜ ํ™”์†Ÿ๊ฐ’์„ [0,1]๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์˜์ƒ ํฌ๊ธฐ๋ฅผ 448 X 448๋กœ ๋ณ€ํ™˜ํ•˜๋ฉฐ BGR ์ˆœ์„œ๋ฅผ RGB๋กœ ๋ฐ”๊พผ๋‹ค.์›๋ณธ ์˜์ƒ์€ img์— ๋‚จ์•„์žˆ๋‹ค.

โˆ™ 19ํ–‰์€ test_img์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์˜์ƒ์„ ์‹ ๊ฒฝ๋ง์— ์ž…๋ ฅํ•œ๋‹ค.

โˆ™ 20ํ–‰์€ ์‹ ๊ฒฝ๋ง์˜ ์ „๋ฐฉ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ, out layers๊ฐ€ ์ถœ๋ ฅํ•œ ํ…์„œ๋ฅผ output3 ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.
์ด๋กœ ์ธํ•ด Ouput3 ๊ฐ์ฒด๋Š” ์•„๋ž˜ 3๊ฐ€์ง€ ํ…์„œ๋ฅผ ๊ฐ–๋Š”๋‹ค.
14×14×85×3,
28×28×85×3,
56×56×85×3 

โˆ™ 22~34ํ–‰์€ output3 ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋ฌผ์ฒด ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ•์Šค ์ •๋ณด์™€ ํ•จ๊ป˜ ๋ฌผ์ฒด ํด๋ž˜์Šค์™€ ์‹ ๋ขฐ๋„ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•œ๋‹ค.
22ํ–‰์€ ๋ฐ•์Šค์™€ ์‹ ๋ขฐ๋„, ํด๋ž˜์Šค์ •๋ณด๋ฅผ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
23ํ–‰์€ ์„ธ ๊ฐœ์˜ ํ…์„œ๋ฅผ ๊ฐ๊ฐ๋ฐ˜๋ณต ์ฒ˜๋ฆฌํ•˜๋ฉฐ
24ํ–‰์€ 85์ฐจ์› ๋ฒกํ„ฐ๋ฅผ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌํ•œ๋‹ค.
85 ์ฐจ์› ๋ฒกํ„ฐ๋Š” (x, y, w, h,o, p1. p2, … p80)์œผ๋กœ ํ‘œํ˜„๋˜๋ฉฐ
์•ž์˜ ๋„ค ์š”์†Œ๋Š” ๋ฐ•์Šค, o๋Š” ์‹ ๋ขฐ๋„, ๋’ค์˜ 80๊ฐœ ์š”์†Œ๋Š” ํด๋ž˜์Šคํ™•๋ฅ ์ด๋‹ค.

โˆ™ 25~27ํ–‰์€ ๋’ค์˜ 80๊ฐœ ์š”์†Œ ๊ฐ’์—์„œ ์ตœ๊ณ  ํ™•๋ฅ ์— ํ•ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์•Œ์•„๋‚ด ํด๋ž˜์Šค ๋ฒˆํ˜ธ๋Š” class_id, ํ™•๋ฅ ์€ confidence์— ์ €์žฅํ•œ๋‹ค.

โˆ™ 28ํ–‰์€ confidence๊ฐ€ 0.5๋ณด๋‹ค ํฌ์ง€ ์•Š์œผ๋ฉด ๋ฒ„๋ฆฐ๋‹ค.
0.5๋ณด๋‹ค ํฌ๋ฉด 29~31ํ–‰์—์„œ [0,1] ๋ฒ”์œ„๋กœ ํ‘œํ˜„๋œ ๋ฐ•์Šค๋ฅผ ์›๋ž˜ ์˜์ƒ ์ขŒํ‘œ ๊ณ„๋กœ ๋ณ€ํ™˜ํ•ด
์™ผ์ชฝ ์œ„์˜ ์œ„์น˜๋ฅผ x์™€ y, ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ w์™€ h์— ์ €์žฅํ•œ๋‹ค.

โˆ™ 32~34ํ–‰์€ ๋ฐ•์Šค์™€ ์‹ ๋ขฐ๋„, ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ฐ•์Šค๋Š” ์™ผ์ชฝ ์œ„์™€ ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ๊ตฌ์„ ์ขŒํ‘œ๋ฅผ ์ €์žฅํ•œ๋‹ค.


โˆ™ 22~34ํ–‰์œผ๋กœ ๊ฒ€์ถœํ•œ ๋ฐ•์Šค๋“ค์—๋Š” ์ƒ๋‹นํ•œ ์ค‘๋ณต์„ฑ์ด ์žˆ๋‹ค.
์ฆ‰, ์ด์ „์‹œ๊ฐ„์— ์„ค๋ช…ํ•œ ๊ทธ๋ฆผ์—์„œ ๋นจ๊ฐ„์ƒ‰ ์œ ๋‹ˆํผ ์„ ์ˆ˜๋ฅผ ๊ฒ€์ถœํ•œ ๋ฐ•์Šค๊ฐ€ ๊ฒ€์€์ƒ‰ ์นธ์—๋งŒ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ  ๊ทธ ์ฃผ์œ„์— ์—ฌ๋Ÿฟ ๋‚˜ํƒ€๋‚˜๋Š” ํ˜„์ƒ์ด๋‹ค.

โˆ™ 36ํ–‰์˜ NMSBoxes ํ•จ์ˆ˜๋Š” ๋ฐ•์Šค๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋น„์ตœ๋Œ€ ์–ต์ œ๋ฅผ ์ ์šฉํ•ด ์ค‘๋ณต์„ฑ์„ ์ œ๊ฑฐํ•œ๋‹ค.

โˆ™ 37ํ–‰ ์€ ๋น„์ตœ๋Œ€ ์–ต์ œ์—์„œ ์‚ด์•„๋‚จ์€ ๋ฐ•์Šค์˜ ์œ„์น˜, ์‹ ๋ขฐ๋„, ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋ชจ์•„ objects ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.

โˆ™ 38ํ–‰์€ objects๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โˆ™ 40ํ–‰์€ contruct yolo_v3 ํ•จ์ˆ˜๋กœ YOLO ๋ชจ๋ธ์„ ๊ตฌ์„ฑํ•œ๋‹ค.

โˆ™ 41 ํ–‰์€ ๋ฌผ์ฒด ํด๋ž˜์Šค๋ฅผ ๊ณ ์œ ํ•œ ์ƒ‰์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์ปฌ๋Ÿฌ ๋ชฉ๋ก์„ ๋งŒ๋“ค์–ด colors ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.

 

 

 


1. YOLO v3๋กœ ์ •์ง€์˜์ƒ์—์„œ Object Detectionํ•˜๊ธฐ

๋ฉ”์ธ ํ”„๋กœ๊ทธ๋žจ์ด ์‹œ์ž‘๋˜๋Š” 
โˆ™ 43ํ–‰์€ ์ž…๋ ฅ ์˜์ƒ์„ ์ฝ์–ด img์— ์ €์žฅํ•œ๋‹ค.
โˆ™ 46ํ–‰์€ yolo_detect ํ•จ์ˆ˜๋กœ ์›๋ณธ ์˜์ƒ img์—์„œ ๋ฌผ์ฒด๋ฅผ ๊ฒ€์ถœํ•ด res์— ์ €์žฅํ•œ๋‹ค.
โˆ™ 48~52ํ–‰์€ res์— ์žˆ๋Š” ๋ฐ•์Šค์™€ ํด๋ž˜์Šค ์ด๋ฆ„, ์‹ ๋ขฐ๋„๋ฅผ ์˜์ƒ์— ํ‘œ์‹œํ•œ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ ์„ ์ˆ˜๋ฅผ ๊ฐ๊ฐ 100%์™€ 94.1% ์‹ ๋ขฐ๋„์˜ person ํด๋ž˜์Šค๋กœ ์ œ๋Œ€๋กœ ๊ฒ€์ถœํ–ˆ๋‹ค.
๋˜ํ•œ ์ถ•๊ตฌ๊ณต์„ 99.9% ์‹ ๋ขฐ๋„๋กœ sports ball ํด๋ž˜์Šค๋กœ ์˜ณ๊ฒŒ ๊ฒ€์ถœํ–ˆ๋‹ค.
img=cv.imread('soccer.jpg')
if img is None: sys.exit('ํŒŒ์ผ์ด ์—†์Šต๋‹ˆ๋‹ค.')

res=yolo_detect(img,model,out_layers)	# YOLO ๋ชจ๋ธ๋กœ ๋ฌผ์ฒด ๊ฒ€์ถœ

for i in range(len(res)):			# ๊ฒ€์ถœ๋œ ๋ฌผ์ฒด๋ฅผ ์˜์ƒ์— ํ‘œ์‹œ
    x1,y1,x2,y2,confidence,id=res[i]
    text=str(class_names[id])+'%.3f'%confidence
    cv.rectangle(img,(x1,y1),(x2,y2),colors[id],2)
    cv.putText(img,text,(x1,y1+30),cv.FONT_HERSHEY_PLAIN,1.5,colors[id],2)

plt.imshow(img[...,::-1])

 

 

 

 

 

 

 

 

 

 

 

 


2. YOLO v3๋กœ ๋น„๋””์˜ค์—์„œ Object Detectionํ•˜๊ธฐ (๋žฉํƒ‘ ์บ ์‚ฌ์šฉ)

โˆ™ 43~64ํ–‰์€ ์›น ์บ ์—์„œ ๋น„๋””์˜ค๋ฅผ ์ฝ์–ด ๋””์Šคํ”Œ๋ ˆ์ดํ•˜๋Š” ์ฝ”๋“œ์— YOLO๋ฅผ ์ ์šฉํ•œ๋‹ค.
โˆ™ 50ํ–‰์€ ๋น„๋””์˜ค์—์„œ ํš๋“ํ•œ ํ˜„์žฌ ํ”„๋ ˆ์ž„์„ yolo_detect ํ•จ์ˆ˜์— ์ž…๋ ฅํ•ด ๋ฌผ์ฒด๋ฅผ ๊ฒ€์ถœํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ res์— ์ €์žฅํ•œ๋‹ค.
โˆ™ 52~56ํ–‰์€ ๊ฒ€์ถœํ•œ ๋ฌผ์ฒด ์ •๋ณด๋ฅผ ์˜์ƒ์— ํ‘œ์‹œํ•œ๋‹ค. 
cap=cv.VideoCapture(0)
if not cap.isOpened(): sys.exit('์นด๋ฉ”๋ผ ์—ฐ๊ฒฐ ์‹คํŒจ')

while True:
    ret,frame=cap.read()
    if not ret: sys.exit('ํ”„๋ ˆ์ž„ ํš๋“์— ์‹คํŒจํ•˜์—ฌ ๋ฃจํ”„๋ฅผ ๋‚˜๊ฐ‘๋‹ˆ๋‹ค.')
        
    res=yolo_detect(frame,model,out_layers)   
 
    for i in range(len(res)):
        x1,y1,x2,y2,confidence,id=res[i]
        text=str(class_names[id])+'%.3f'%confidence
        cv.rectangle(frame,(x1,y1),(x2,y2),colors[id],2)
        cv.putText(frame,text,(x1,y1+30),cv.FONT_HERSHEY_PLAIN,1.5,colors[id],2)
    
    cv.imshow("Object detection from video by YOLO v.3",frame)
    
    key=cv.waitKey(1) 
    if key==ord('q'): break

 

'Gain Study > Vision' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Gain Study_CV]03. Advanced Vision  (2) 2024.01.08
[Gain Study_CV]02-1. Object Detection  (0) 2023.09.18
[Gain Study_CV]01. Object Recognition(Classification, Semantic Segmentation)  (0) 2023.09.15

+ Recent posts