๐บ ๋์์ ๋ณด๊ธฐ ๐ฌ
๐ ๋ธ๋ก๊ทธ ํ๋ก์ ํธ ๋งํฌ ๐
Cigarette Detection yolo
์ด ํ๋ก์ ํธ๋ YOLOv8 (You Only Look Once version 8) ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ๊ฐ์ฒด ํ์ง๋ฅผ ์ํํ๊ณ , ํน์ ๊ฐ์ฒด (์: ๋ด๋ฐฐ)๊ฐ ํ์ง๋์์ ๋ ์๋ฆผ ์๋ฆฌ๋ฅผ ์ธ๋ฆฌ๋๋ก ๊ตฌํํ ์์คํ ์ ๋๋ค. ์ด ์์คํ ์ OpenCV, Ultralytics YOLO, ๊ทธ๋ฆฌ๊ณ pygame ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ ์น์บ ์์ ์ค์๊ฐ ๋น๋์ค ์คํธ๋ฆผ์ ์บก์ฒํ๊ณ , ์ด๋ฅผ ์ฒ๋ฆฌํ์ฌ ํ์ง๋ ๊ฐ์ฒด์ ๋ํ ์๊ฐ์ ํ์ ๋ฐ ์๋ฆฌ ์๋ฆผ์ ์ ๊ณตํฉ๋๋ค.
์ด ์์คํ ์ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์ฑ ์์๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค:
- YOLOv8 ๋ชจ๋ธ์ ์ฌ์ฉํ ๊ฐ์ฒด ํ์ง
- ์น์บ ๋น๋์ค ์คํธ๋ฆผ์ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ์์ ์ ๋ ฅ
- ์๋ฆผ ์๋ฆฌ: ํน์ ๊ฐ์ฒด(์: ๋ด๋ฐฐ)๊ฐ ํ์ง๋๋ฉด ์๋ฆฌ๋ฅผ ์ฌ์
- ์ค๋ ๋ ๊ธฐ๋ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ: ์๋ฆผ ์๋ฆฌ์ ๊ฐ์ฒด ํ์ง ์ฒ๋ฆฌ ๋ถ๋ฆฌ
-
YOLOv8 ๋ชจ๋ธ๋ก ์ค์๊ฐ ๊ฐ์ฒด ํ์ง:
- ์น์บ ์์ ์ ๋ ฅ๋ ์์์ YOLOv8 ๋ชจ๋ธ๋ก ์ฒ๋ฆฌํ์ฌ ๊ฐ์ฒด๋ฅผ ํ์งํฉ๋๋ค.
- ํ์ง๋ ๊ฐ์ฒด๋ Bounding Box์ ํจ๊ป ํ๋ฉด์ ํ์๋ฉ๋๋ค.
-
์๋ฆผ ์๋ฆฌ:
- ํน์ ๊ฐ์ฒด(์: ๋ด๋ฐฐ)๊ฐ ํ์ง๋๋ฉด ์๋ฆผ ์๋ฆฌ๋ฅผ ์ฌ์ํฉ๋๋ค.
- ์๋ฆฌ๋
pygame
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์๋๋ฉฐ, ์๋ฆฌ๊ฐ ๋ฐ๋ณต๋์ง ์๋๋ก ๊ด๋ฆฌํฉ๋๋ค.
-
์ค๋ ๋๋ฅผ ํ์ฉํ ๋น๋๊ธฐ ์๋ฆฌ ์ฌ์:
- ์๋ฆฌ ์ฌ์์ ๋ณ๋์ ์ค๋ ๋์์ ์ฒ๋ฆฌ๋์ด, ๊ฐ์ฒด ํ์ง์ ๋์์ ์๋ฆฌ๊ฐ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์๋ ์ ์๋๋ก ๊ตฌํ๋ฉ๋๋ค.
-
์ค์๊ฐ ์น์บ ์คํธ๋ฆฌ๋ฐ:
- OpenCV๋ฅผ ์ด์ฉํ์ฌ ์น์บ ์์ ์ค์๊ฐ์ผ๋ก ์์์ ์บก์ฒํ๊ณ , ์ด๋ฅผ ํ์ํฉ๋๋ค.
์ด ์์คํ ์ ๋ ์ฃผ์ ํ๋ก์ธ์ค๋ฅผ ๋ณํํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค: ๊ฐ์ฒด ํ์ง์ ์๋ฆฌ ์ฌ์. ์ ์ฒด ์์คํ ์ ๋์ ํ๋ฆ์ ์๋์ ๊ฐ์ต๋๋ค.
-
YOLOv8 ๋ชจ๋ธ ๋ก๋:
- ํ์ต๋ YOLOv8 ๋ชจ๋ธ ํ์ผ(
trained_model.pt
)์ ๋ก๋ํฉ๋๋ค. - ์ด ๋ชจ๋ธ์ ์น์บ ์์ ์ค์๊ฐ์ผ๋ก ์บก์ฒ๋ ์ด๋ฏธ์ง์์ ๊ฐ์ฒด๋ฅผ ํ์งํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ํ์ต๋ YOLOv8 ๋ชจ๋ธ ํ์ผ(
-
์น์บ ์์ ์บก์ฒ:
cv2.VideoCapture(0)
์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ ์นด๋ฉ๋ผ(Webcam)์์ ๋น๋์ค ์คํธ๋ฆผ์ ๊ฐ์ ธ์ต๋๋ค.- ๊ฐ ํ๋ ์์ YOLOv8 ๋ชจ๋ธ์ ์ ๋ฌํ์ฌ ๊ฐ์ฒด ํ์ง๋ฅผ ์ํํฉ๋๋ค.
-
๊ฐ์ฒด ํ์ง ๋ฐ ์๋ฆผ ์๋ฆฌ ์ฌ์:
- YOLOv8 ๋ชจ๋ธ์ ๊ฐ์ฒด๋ฅผ ํ์งํ์ฌ Bounding Box๋ฅผ ์ด๋ฏธ์ง์ ๊ทธ๋ฆฝ๋๋ค.
- ํ์ง๋ ๊ฐ์ฒด๊ฐ 'cigarette'๋ผ๋ฉด ์๋ฆผ ์๋ฆฌ(
alert_sound.mp3
)๊ฐ ์ฌ์๋ฉ๋๋ค. - ์๋ฆฌ๋
pygame.mixer.music
์ ์ฌ์ฉํ์ฌ ์ฌ์๋๋ฉฐ, ์๋ฆฌ ์ฌ์ ์ฌ๋ถ๋ ๋ณ๋์ ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
-
๊ฐ์ฒด ํ์ง ๊ฒฐ๊ณผ ์ถ๋ ฅ:
- ๊ฐ์ฒด ํ์ง ๊ฒฐ๊ณผ(ํ์ง๋ ํด๋์ค ๋ฐ ํด๋น ์์น)๋ Bounding Box ํํ๋ก ์ค์๊ฐ ๋น๋์ค์ ์ค๋ฒ๋ ์ด๋ฉ๋๋ค.
- ํ์ง๋ ๊ฐ์ฒด๊ฐ ์๋ค๋ฉด, ํ์ง๋์ง ์์ ์ํ๋ก ๋น๋์ค๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
# YOLOv8 ๋ชจ๋ธ ๋ก๋ (ํ์ตํ ๋ชจ๋ธ ํ์ผ ๊ฒฝ๋ก)
model = YOLO('trained_model.pt')
# ์น์บ ์ด๊ธฐ (๊ธฐ๋ณธ ์นด๋ฉ๋ผ 0๋ฒ ์ฌ์ฉ)
cap = cv2.VideoCapture(0)
YOLO('trained_model.pt')
: YOLOv8 ๋ชจ๋ธ์ ๋ก๋ํฉ๋๋ค. ์ด ๋ชจ๋ธ์ ์์ ์ด ํ์ตํ ๊ฐ์ฒด ์ธ์ ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ํ์ง๋ฅผ ์ํํฉ๋๋ค.cv2.VideoCapture(0)
: OpenCV๋ฅผ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ ์น์บ ์์ ๋น๋์ค ์คํธ๋ฆผ์ ์บก์ฒํฉ๋๋ค.
# ์๋ฆผ ์๋ฆฌ ํ์ผ ๊ฒฝ๋ก (์๋ฆฌ ํ์ผ์ ํ๋ก์ ํธ ํด๋์ ๋ฃ๊ณ ์ฌ์ฉ)
alert_sound = 'alert_sound.mp3'
# pygame ์ด๊ธฐํ
pygame.mixer.init()
# ์๋ฆฌ ์ฌ์์ ์ํ ๋น๋๊ธฐ ํจ์
def play_alert_sound():
while True:
pygame.mixer.music.load(alert_sound)
pygame.mixer.music.play()
print("์๋ฆฌ ์ฌ์๋จ!") # ์๋ฆฌ ์ฌ์ ์ ์ถ๋ ฅ
time.sleep(1) # ๋๋ฌด ์์ฃผ ๋ฐ๋ณต๋์ง ์๋๋ก ์ ์ ๋๊ธฐ
# ์๋ฆฌ ์ฌ์์ ์ํ ์ค๋ ๋ ์์
alert_thread = threading.Thread(target=play_alert_sound, daemon=True)
alert_thread.start()
pygame.mixer.init()
:pygame
์ ๋ฏน์ ๋ชจ๋์ ์ด๊ธฐํํฉ๋๋ค. ์๋ฆฌ ํ์ผ์ ์ฌ์ํ ์ค๋น๋ฅผ ํฉ๋๋ค.play_alert_sound()
: ์๋ฆผ ์๋ฆฌ๋ฅผ ๋ฌดํ ๋ฐ๋ณตํ์ฌ ์ฌ์ํ๋ ํจ์์ ๋๋ค. ์๋ฆฌ๊ฐ ์ฌ์๋ ๋๋ง๋ค 1์ด ๊ฐ๊ฒฉ์ ๋๊ณ ๋ฐ๋ณต๋ฉ๋๋ค.threading.Thread(target=play_alert_sound, daemon=True)
: ๋ณ๋์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฆฌ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ ๊ฐ์ฒด ํ์ง์ ์๋ฆฌ ์ฌ์์ด ๋์์ ์ด๋ฃจ์ด์ง ์ ์๊ฒ ํฉ๋๋ค.
# YOLOv8 ๋ชจ๋ธ๋ก ๊ฐ์ฒด ํ์ง
results = model(frame)
# ๊ฒฐ๊ณผ์์ ํ์ง๋ ๊ฐ์ฒด ํ์ธ
cigarette_detected = False
# results.pred[0]๋ YOLO ๋ชจ๋ธ์ด ๋ฐํํ๋ ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ํ ํ์ง ๊ฒฐ๊ณผ์
๋๋ค
for result in results[0].boxes:
class_id = int(result.cls.item()) # ๊ฒฐ๊ณผ ํด๋์ค ID ์ถ์ถ
if model.names[class_id] == 'cigarette': # 'cigarette' ํด๋์ค๊ฐ ํ์ง๋์๋์ง ํ์ธ
cigarette_detected = True
break
results = model(frame)
: ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ ๋ ฅ๋frame
์์ ๊ฐ์ฒด ํ์ง๋ฅผ ์ํํฉ๋๋ค.results[0].boxes
: ํ์ง๋ ๊ฐ์ฒด๋ค์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๊ฐ ๊ฐ์ฒด๋ ํด๋์ค ID์ ๊ฒฝ๊ณ ์์ ์ขํ ๋ฑ์ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค.if model.names[class_id] == 'cigarette'
: ํ์ง๋ ๊ฐ์ฒด๊ฐ 'cigarette'์ธ์ง ํ์ธํ๊ณ , ํด๋น ๊ฐ์ฒด๊ฐ ๋ฐ๊ฒฌ๋๋ฉดcigarette_detected
๋ฅผTrue
๋ก ์ค์ ํฉ๋๋ค.
if cigarette_detected:
print("Cigarette detected!") # ํ์ง ์ ์ถ๋ ฅ
if not is_playing: # ์๋ฆฌ๊ฐ ์ฌ์ ์ค์ด ์๋๋ฉด
pygame.mixer.music.set_volume(1.0) # ๋ณผ๋ฅจ์ ์ต๋๊ฐ์ผ๋ก ์ค์
is_playing = True
else:
print("No cigarette detected!") # ํ์ง๋์ง ์์ผ๋ฉด ์ถ๋ ฅ
pygame.mixer.music.set_volume(0.0) # ๋ณผ๋ฅจ์ 0์ผ๋ก ์ค์
is_playing = False
pygame.mixer.music.set_volume(1.0)
: ๋ด๋ฐฐ๊ฐ ํ์ง๋ ๊ฒฝ์ฐ ์๋ฆผ ์๋ฆฌ๋ฅผ ์ต๋ ๋ณผ๋ฅจ์ผ๋ก ์ค์ ํ์ฌ ์ฌ์ํฉ๋๋ค.pygame.mixer.music.set_volume(0.0)
: ๋ด๋ฐฐ๊ฐ ํ์ง๋์ง ์์ ๊ฒฝ์ฐ ์๋ฆฌ๋ฅผ ์์๊ฑฐ๋ก ์ค์ ํฉ๋๋ค.
# ํ์ง๋ ๊ฒฐ๊ณผ๋ฅผ ์์์ ํ์
annotated_frame = results[0].plot() # ํ์ง๋ ๊ฐ์ฒด ํ์
# ์ค์๊ฐ ์น์บ ์์ ์ถ๋ ฅ
cv2.imshow('Webcam Feed', annotated_frame)
results[0].plot()
: ํ์ง๋ ๊ฐ์ฒด์ ๋ํ Bounding Box๋ฅผ ๊ทธ๋ ค์ ๋ฐํํฉ๋๋ค.cv2.imshow('Webcam Feed', annotated_frame)
: ์ค์๊ฐ์ผ๋ก ์ฒ๋ฆฌ๋ ํ๋ ์์ ํ๋ฉด์ ์ถ๋ ฅํฉ๋๋ค.
# ์น์บ ๋ฐ ์ฐฝ ๋ซ๊ธฐ
cap.release()
cv2.destroyAllWindows()
cap.release()
: ์น์บ ์คํธ๋ฆฌ๋ฐ์ ์ข ๋ฃํฉ๋๋ค.cv2.destroyAllWindows()
: OpenCV ์ฐฝ์ ๋ซ์ต๋๋ค.
์ด ์์คํ
์ YOLOv8 ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ค์๊ฐ์ผ๋ก ๊ฐ์ฒด๋ฅผ ํ์งํ๊ณ , ํน์ ๊ฐ์ฒด๊ฐ ํ์ง๋๋ฉด ์๋ฆผ ์๋ฆฌ๋ฅผ ์ฌ์ํ๋ ๊ฐ๋จํ ๊ฐ์ฒด ํ์ง ์์คํ
์
๋๋ค. pygame
๊ณผ threading
์ ํ์ฉํ์ฌ ์๋ฆฌ ์ฌ์์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , OpenCV๋ฅผ ์ฌ์ฉํ์ฌ ์ค์๊ฐ์ผ๋ก ์น์บ ์์์ ํ์ง ๊ฒฐ๊ณผ๋ฅผ ํ์ํฉ๋๋ค.
results.csv