YOLOv9 객체 감지 튜토리얼
세계에서 가장 빠르고 정확한 객체 감지기 중 하나를 사용해 추론을 실행하고, OpenCV로 웹캠에 결과를 표시하며, 감지 결과를 추적하는 방법. 이 글은 AI 번역본입니다. 오역이 있을 수 있으니 댓글로 알려 주세요.
Created on September 12|Last edited on September 12
Comment
YOLO는 “you only look once”의 약자로, 속도와 정확도로 인정받는 최첨단 객체 감지 모델입니다. 이 가이드에서는 최신 버전인 YOLOv9를 OpenCV와 결합해 실시간 객체 감지를 구현하는 방법을 살펴보겠습니다.

YOLO란 무엇인가요?
YOLOv9은 …의 약자입니다 단 한 번만 본다 버전 9로, 단일 합성곱 신경망을 활용하는 매우 빠른 객체 감지 프레임워크입니다. 전통적인 객체 감지 시스템이 이미지를 픽셀 단위로 스캔하는 것과 달리, YOLOv9은 전체 이미지를 한 번에 처리하여 감지 속도를 크게 높입니다.
2024년 4월에 공개된 YOLOv9은 Programmable Gradient Information(PGI)와 Generalized Efficient Layer Aggregation Network(GELAN)과 같은 혁신적인 기법을 도입해 컴퓨터 비전 작업에서의 데이터 손실과 계산 효율 문제를 해결합니다. 이러한 혁신 덕분에 YOLOv9은 정밀도와 속도에서 새로운 기준을 세우며, 탁월한 실시간 객체 감지 성능을 구현합니다.

이러한 향상 덕분에 YOLOv9은 이전 YOLO 모델보다 더 높은 평균 평균 정밀도(mAP)를 달성할 수 있습니다 YOLOv8, YOLOv7, 및 YOLOv5 다음과 비교하여 벤치마크했을 때 MS COCO 데이터셋.
YOLOv9 시작하기
시작하려면 다음 패키지들을 설치해야 합니다:
pip install opencv-python ultralytics pytubefix requests pillow
다음으로, 시스템에 CUDA가 설치된 NVIDIA GPU가 있으면 매우 도움이 됩니다. 그렇다고 해서 없어도 괜찮습니다. YOLO는 문제없이 사용할 수 있습니다.
다음은 YOLOv9로 추론을 실행하는 스크립트입니다:
from ultralytics import YOLOimport requestsfrom PIL import Imagefrom io import BytesIOimport os# Download the YOLOv9 model if it doesn't existmodel_path = "yolov9m.pt"# Load the pretrained YOLOv9 modelmodel = YOLO(model_path)# Download the image from the URLimage_url = "https://di-uploads-pod25.dealerinspire.com/koenigseggflorida/uploads/2019/08/Koenigsegg_TheSquad_3200x2000-UPDATED.jpg"response = requests.get(image_url)img = Image.open(BytesIO(response.content))# Set the confidence and IoU thresholdsconfidence_threshold = 0.5iou_threshold = 0.4# Predict with the model using the set thresholdsresults = model.predict(img, conf=confidence_threshold, iou=iou_threshold)results[0].show()
간단한 추론 스크립트는 필요한 라이브러리를 임포트하는 것으로 시작합니다:
- ultralytics 라이브러리의 YOLO
- requests
- 이미지 처리를 위한 PIL
그다음 YOLOv9 모델은 모델 경로를 지정해 불러옵니다. 이때 지정한 경로가 실제로 존재하는 모델 파일의 경로일 필요는 없습니다. 지정한 위치에 모델이 없으면 라이브러리가 자동으로 다운로드합니다. 모델이 로드되면 샘플 이미지에 대해 추론을 수행합니다. 추론 결과로 감지된 객체와 해당 바운딩 박스가 화면에 표시됩니다.
이 스크립트는 사전 학습된 모델을 로드하고 정적 이미지에서 객체를 감지하도록 실행하는 기본 동작을 보여 줍니다.

YOLOv9 추론 하이퍼파라미터
YOLO 객체 감지 모델에서 신뢰도 임계값과 IoU(Intersection over Union) 임계값은 매우 중요한 하이퍼파라미터입니다.
신뢰도 임계값 유효한 검출로 인정되기 위해 detection이 가져야 하는 최소 신뢰도 점수를 결정합니다. 신뢰도 임계값을 높이면 거짓 양성을 줄여 가장 확실한 검출만 표시되도록 합니다. 반대로 임계값을 낮추면 확실성이 떨어지는 검출까지 포함해 검출 수가 늘어나며, 높은 민감도가 필요한 애플리케이션에서는 유용할 수 있습니다.
IoU 임계값 비최대 억제(NMS) 과정에서 중복된 바운딩 박스를 제거하는 데 사용됩니다. IoU는 두 바운딩 박스 간의 겹침 정도를 측정합니다. IoU 임계값을 높이면 바운딩 박스 간 더 많은 겹침을 허용하므로, 서로 가까운 검출을 병합할 가능성이 커집니다. 반대로 IoU 임계값을 낮추면 모델이 더 엄격해져서, 가장 구별되는 바운딩 박스만 유지합니다.
이러한 임계값의 선택은 애플리케이션의 요구 사항에 따라 달라집니다. 예를 들어 보안 시스템에서는 높은 신뢰도 임계값과 낮은 IoU 임계값을 사용해, 겹치지 않는 명확한 바운딩 박스로 매우 가능성이 높은 위협만 검출되도록 하는 것이 선호될 수 있습니다. 반대로 의료 영상에서는 잠재적인 이상 소견을 놓치지 않도록 더 낮은 임계값을 사용할 수 있습니다.
웹캠에서 YOLOv9 사용하기
또한 웹캠을 사용해 모델의 성능을 실시간으로 시각화할 수 있습니다:
import cv2from ultralytics import YOLOimport os# Download the YOLOv9 model if it doesn't existmodel_path = "yolov9c.pt"# Load the pretrained YOLOv9 modelmodel = YOLO(model_path)# Initialize the webcam# 0 is the default camera. If you have multiple cameras(ex: an external one on your laptop) you may need to change this number.cap = cv2.VideoCapture(0)if not cap.isOpened():print("Error: Could not open webcam.")exit()while True:ret, frame = cap.read()if not ret:print("Error: Could not read frame.")break# Convert the frame to the format expected by YOLOframe_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# Run YOLO model on the frameresults = model.predict(frame_rgb)# Draw bounding boxes on the framefor box in results[0].boxes:x1, y1, x2, y2 = map(int, box.xyxy.tolist()[0])class_id = int(box.cls)class_name = results[0].names[class_id]confidence = box.conf.item()if confidence < .8:continue# Draw rectangle and label on the framecv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)label = f"{class_name}: {confidence:.2f}"cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# Display the frame with detectionscv2.imshow("YOLO Webcam Detection", frame)# Break the loop if the user presses 'q'if cv2.waitKey(1) & 0xFF == ord('q'):break# Release the webcam and close the windowcap.release()cv2.destroyAllWindows()
이 스크립트는 OpenCV를 사용해 웹캠을 초기화하고 VideoCapture 웹캠에서 비디오 프레임을 캡처할 수 있도록 준비하는 함수입니다. 이어서 웹캠이 정상적으로 열렸는지 확인하고, 열지 못한 경우 오류 메시지를 출력하고 프로그램을 종료합니다. 웹캠이 초기화되면 스크립트는 루프에 들어가 웹캠으로부터 프레임을 연속적으로 캡처합니다. 각 프레임은 YOLO가 RGB 입력을 기대하므로 BGR에서 RGB 형식으로 변환됩니다. 변환된 프레임은 이후 YOLO 모델에 전달되어 객체 검출을 수행합니다.
다음 줄에서: cap = cv2.VideoCapture(0) 0은 기본 카메라입니다. 카메라가 여러 대인 경우(예: 노트북에 연결된 외장 카메라) 이 숫자를 변경해야 할 수 있습니다.
💡
Zoom 등으로 출력을 보내려면 가상 카메라를 설정해야 합니다. OBS(무료)를 사용해 설정하는 매우 간단한 방법은 본문에서 확인할 수 있습니다. YOLOv5 객체 감지 튜토리얼: Zoom용 바운딩 박스 웹캠 설정 (해당 링크로 이동하면 OBS 설정 안내로 바로 넘어갑니다.)
프레임 처리 및 표시
YOLO 모델은 프레임을 처리해 감지된 객체가 포함된 결과를 반환합니다. 스크립트는 각 감지 객체에 대해 바운딩 박스 좌표, 클래스 ID, 클래스 이름, 신뢰도 점수를 추출합니다. 그런 다음 감지된 객체 주위에 사각형을 그린 뒤 클래스 이름과 신뢰도 점수로 라벨을 표시합니다. 이렇게 처리된 프레임은 OpenCV의 imshow 함수.
사용자가 ‘q’를 눌러 종료할 때까지 루프는 프레임을 계속 캡처하고 처리합니다. 마지막으로 웹캠을 해제하고 모든 OpenCV 창을 닫아 리소스를 정리합니다.

나는 아마 인간성 지수 94%쯤인 것 같네요. 개인적인 관점에서 집중해 볼 지점이에요.
YouTube 동영상에서 YOLO를 실행하고 싶다면 역시 가능합니다! 아래 스크립트는 YouTube 동영상을 다운로드한 뒤, 각 프레임에 모델을 적용하고 결과를 표시합니다. 다만 이 방법은 교육 목적과 소량의 동영상에 한해 사용할 것을 권장합니다. 대규모 데이터 수집 용도로의 스크레이핑에는 권장하지 않습니다.
import cv2from ultralytics import YOLOimport osimport argparsefrom pytubefix import YouTube# Function to download YouTube video using pytubefixdef download_youtube_video(url, output_path):try:yt = YouTube(url)stream = yt.streams.get_highest_resolution()stream.download(output_path=output_path, filename="downloaded_video.mp4")print("Video downloaded successfully.")except Exception as e:print(f"Error downloading video: {e}")# Parse command-line argumentsparser = argparse.ArgumentParser(description="YOLOv5 Object Detection on YouTube Video")parser.add_argument("url", type=str, help="URL of the YouTube video to process")args = parser.parse_args()# Download the YOLOv9 model if it doesn't existmodel_path = "yolov9c.pt"# Load the pretrained YOLOv9 modelmodel = YOLO(model_path)# Download YouTube videoyoutube_url = args.urldownload_youtube_video(youtube_url, os.getcwd())# Open the downloaded videovideo_path = "downloaded_video.mp4"cap = cv2.VideoCapture(video_path)if not cap.isOpened():print("Error: Could not open video.")exit()while True:ret, frame = cap.read()if not ret:print("End of video.")break# Convert the frame to the format expected by YOLOframe_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# Run YOLO model on the frameresults = model.predict(frame_rgb)# Draw bounding boxes on the framefor box in results[0].boxes:x1, y1, x2, y2 = map(int, box.xyxy.tolist()[0])class_id = int(box.cls)class_name = results[0].names[class_id]confidence = box.conf.item()if confidence < 0.5:continue# Draw rectangle and label on the framecv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)label = f"{class_name}: {confidence:.2f}"cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# Display the frame with detectionscv2.imshow("YOLO Video Detection", frame)# Break the loop if the user presses 'q'if cv2.waitKey(1) & 0xFF == ord('q'):break# Release the video and close the windowcap.release()cv2.destroyAllWindows()
이 스크립트는 필요한 라이브러리를 임포트하고 YOLOv9 모델을 초기화하는 것으로 시작합니다. 또한 YouTube 동영상을 다운로드하기 위한 함수를 포함하며, 이는 pytubefix 라이브러리입니다. 동영상은 사용 가능한 최고 해상도로 다운로드되어 지정한 출력 경로에 저장됩니다.
명령줄 인수를 파싱해 처리할 YouTube 동영상의 URL을 가져옵니다. 그런 다음 YOLOv9 모델을 로드하고, YouTube 동영상을 현재 작업 디렉터리에 다운로드합니다. 다운로드된 동영상은 OpenCV의 VideoCapture 함수를 사용해 열어 처리합니다.
감지된 객체는 웹캠 구현과 마찬가지로 바운딩 박스와 라벨로 강조 표시됩니다. 처리된 프레임은 OpenCV의 imshow 함수로 표시됩니다. 루프는 동영상이 끝날 때까지 또는 사용자가 ‘q’를 눌러 종료할 때까지 계속됩니다. 마지막으로 동영상 리소스를 해제하고, 모든 OpenCV 창을 닫아 리소스를 정리합니다.

Weave로 데이터 추적하기
Weave 단 한 줄의 코드로 모델 입력과 출력의 로깅 및 디버깅, 평가 구축, 실험부터 프로덕션까지의 정보 정리를 매끄럽게 처리할 수 있습니다. 다음은 YOLOv9 추론 파이프라인에 Weave를 통합하는 방법입니다.
from ultralytics import YOLOimport requestsfrom PIL import Imagefrom io import BytesIOimport osimport wandbimport weave# Initialize Weave and wandb with the same project nameproject_name = "yolo_training"weave.init(project_name)run = wandb.init(project=project_name)# Use the specified artifactartifact = run.use_artifact('byyoung3/model-registry/yolo:v0', type='model')artifact_dir = artifact.download()# Define the path to the downloaded modelmodel_path = os.path.join(artifact_dir, "best.pt")# Load the pretrained YOLOv9 modelmodel = YOLO(model_path)# Function to run inference on a single image@weave.opdef run_inference(image: Image.Image) -> dict:try:# Save the image locally for predictionlocal_image_path = 'temp_image.jpg'image.save(local_image_path)# Run the YOLO model on the image with adjusted NMS thresholdresults = model.predict(local_image_path, conf=0.7, iou=0.2)# Draw bounding boxes on the image and save the resultresults[0].save(local_image_path)result_image = Image.open(local_image_path)# Extract predictionspredictions = []for box in results[0].boxes:class_id = int(box.cls)class_name = results[0].names[class_id]confidence = box.conf.item()coordinates = box.xyxy.tolist()predictions.append({'class': class_name,'confidence': confidence,'coordinates': coordinates})# Prepare the resultsresult_data = {'result_image': result_image,'predictions': predictions}return result_dataexcept Exception as e:return {'error': str(e)}# Download the image from the URLimage_url = "https://i.ytimg.com/vi/7FmHydF9Gvg/hqdefault.jpg"response = requests.get(image_url)image = Image.open(BytesIO(response.content))# Run inference using the downloaded imageinference_result = run_inference(image)print(inference_result)
우리 스크립트에서는 모델의 성능을 추적하고 평가하기 위해 Weave를 통합했습니다. 원활한 동기화를 위해 Weave와 Weights & Biases를 동일한 프로젝트 이름으로 구성했습니다. 그런 다음 데코레이터가 적용된 함수를 만들었으며, @weave.op추론을 위해 PIL 이미지를 직접 처리합니다. 최신 Weave 업데이트로 이미지를 base64 데이터 URL로 변환할 필요가 없어져 로깅 과정이 한층 더 간단하고 효율적입니다.
추론 함수는 원시 이미지를 처리하고 모델을 실행한 뒤, 바운딩 박스와 탐지 세부 정보를 포함한 예측과 함께 이미지를 직접 로깅합니다. 이 방식은 작업 흐름을 단순화하여 클래스 이름, 신뢰도 점수, 좌표 등 모델 출력의 명확하고 직접적인 추적이 가능하게 합니다.
Weave는 모든 관련 출력을 효율적으로 로깅하여 실험부터 프로덕션까지 모델의 동작을 모니터링하고 디버그하며 이해하기 쉽게 만들어 줍니다. 아래는 Weave 내부에서 로깅된 데이터가 어떻게 보이는지에 대한 미리 보기입니다.

속도가 전부다
YOLOv9와 OpenCV를 활용한 실시간 객체 탐지 가이드를 마무리하며, YOLOv9가 다양한 활용 분야에서 실용적이고 효율적인 해법을 제공한다는 점이 분명해졌습니다. 정적 이미지 분석부터 실시간 웹캠과 YouTube 동영상 처리에 이르기까지, 제시한 예제들은 모델의 효과성과 유연성을 잘 보여줍니다.
OpenCV로 YOLOv9를 구현하는 과정은 간단하며, 속도와 정확도 면의 향상 덕분에 개발자와 연구자 모두에게 유용한 도구가 됩니다. 보안 시스템, 자율 주행 차량, 또는 신뢰할 수 있는 객체 탐지가 필요한 그 어떤 프로젝트든 YOLOv9는 견고한 기반을 제공합니다.
또한 모델의 파인튜닝에 관심이 있으시다면, 곧 YOLO를 활용한 파인튜닝 가이드도 공개할 예정이니 기대해 주세요!
Getting started fine-tuning with the Mistral API
How to fine-tune Mistral-Small using the Mistral API and W&B Weave.
Self-Supervised Image Recognition with IJEPA
Grokking: Improved generalization through over-overfitting
One of the most mysterious phenomena in deep learning; Grokking is the tendency of neural networks to improve generalization by sustained overfitting.
6 "gotchas" in machine learning—and how to avoid them
ML is hard and you can't plan for everything. Here are a few things I've learned and a few tips to avoid common missteps
Add a comment