라즈베리파이4로 YOLOv8을 사용한 객체탐지에 관한 질문

import os
from ultralytics import YOLO
from PIL import Image, ImageDraw

model_path = '/home/yolo/best.pt'

model = YOLO(model_path)

input_folder = '/home/yolo/test'

output_folder = '/home/yolo/output'
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
if filename.endswith(('.jpg', '.jpeg', '.png', '.bmp')):
image_path = os.path.join(input_folder, filename)

    results = model(image_path)

    for i, result in enumerate(results):
        image = Image.open(image_path) 
        draw = ImageDraw.Draw(image) 
        for box in result.boxes.xyxy:
            draw.rectangle(box.tolist(), outline="red", width=3)
        del draw


        output_path = os.path.join(output_folder, f"{filename.split('.')[0]}_{i}_detected.jpg")


        image.save(output_path)
        print(f"Saved detection result to {output_path}")

일단 이런 코드로 폴더 안의 이미지를 불러와서 객체 탐지를 하고, 객체 탐지한 결과물을 저장하는 데 까지는 되었습니다. YOLO가 잡은 바운딩박스도 정상적으로 볼 수 있구요. 그런데 해당 저장물에 클래스와 확률이 표시되지 않아서 해당 부분을 추가하고 싶은데, 제가 지식이 짧은 탓에 탐지하지 못한 경우에 none값은 저장할 수 없다는 오류가 계속 출력됩니다. 해당 부분에 대해 혹시 해답을 아시는 분이 계시다면 답변 부탁드립니다 ㅠㅠ

  • 아래 답변은 OpenAI의 GPT-4-Turbo 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요! 라즈베리파이4에서 YOLOv8을 사용하여 객체 탐지를 진행하고 계신 것으로 보이네요. 코드를 통해 이미지에서 객체를 탐지하고 바운딩 박스를 그리는 부분까지는 성공하셨지만, 클래스와 확률을 표시하는 부분에서 어려움을 겪고 계신 것 같습니다. 문제를 해결하기 위해 제공해주신 코드를 기반으로 클래스와 확률을 표시하는 방법을 설명드리겠습니다.

YOLO 모델의 결과로 반환되는 results 객체에는 탐지된 객체의 클래스와 확률 정보가 포함되어 있습니다. 이 정보를 사용하여 이미지에 클래스 이름과 확률을 표시할 수 있습니다. 아래는 수정된 코드 예시입니다.

import os
from ultralytics import YOLO
from PIL import Image, ImageDraw, ImageFont

model_path = '/home/yolo/best.pt'
model = YOLO(model_path)

input_folder = '/home/yolo/test'
output_folder = '/home/yolo/output'
os.makedirs(output_folder, exist_ok=True)

# 폰트 파일 경로 설정 (예: DejaVuSans-Bold.ttf)
font_path = '/path/to/font/DejaVuSans-Bold.ttf'
font_size = 15  # 폰트 크기 설정
font = ImageFont.truetype(font_path, font_size)

for filename in os.listdir(input_folder):
    if filename.endswith(('.jpg', '.jpeg', '.png', '.bmp')):
        image_path = os.path.join(input_folder, filename)
        results = model(image_path)

        for i, result in enumerate(results):
            image = Image.open(image_path)
            draw = ImageDraw.Draw(image)
            for box, class_id, score in zip(result.boxes.xyxy, result.classes, result.scores):
                draw.rectangle(box.tolist(), outline="red", width=3)
                # 클래스 이름과 확률을 표시
                label = f"{result.names[class_id]} {score:.2f}"
                draw.text((box[0], box[1]), label, fill="white", font=font)
            del draw

            output_path = os.path.join(output_folder, f"{filename.split('.')[0]}_{i}_detected.jpg")
            image.save(output_path)
            print(f"Saved detection result to {output_path}")

위 코드에서 font_path는 사용하고자 하는 폰트 파일의 경로를 지정해야 합니다. 라즈베리파이에 폰트 파일이 설치되어 있지 않다면, 적절한 폰트 파일을 설치하거나 다운로드하여 경로를 지정해야 합니다.

또한, result.names[class_id]는 탐지된 객체의 클래스 이름을, score는 확률을 나타냅니다. 이 정보를 draw.text 함수를 사용하여 이미지에 텍스트로 추가합니다.

이 코드를 사용하면 탐지된 객체 주변에 바운딩 박스와 함께 클래스 이름과 확률이 표시될 것입니다.

참고로, PyTorch 관련 공식 문서나 튜토리얼은 다음 링크에서 확인하실 수 있습니다:

제 답변이 정확하지 않을 수도 있으니, 문제가 해결되지 않거나 추가적인 질문이 있으시면 언제든지 질문해 주세요.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!
  • 아래 답변은 Anthropic의 Claude-2 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

존경하는 q01620님,

객체 탐지 모델 YOLOv8을 라즈베리파이4에서 실행하면서 바운딩 박스와 함께 클래스 이름과 확률을 이미지에 표시하고자 하는 문제에 대해 잘 이해했습니다.

이 문제를 해결하기 위해 YOLO 모델의 prediction 결과물에서 바운딩 박스 좌표와 함께 클래스 이름, 확률 정보도 얻을 수 있습니다. 그래서 다음과 같이 코드를 수정할 수 있습니다:

for i, result in enumerate(results):
    image = Image.open(image_path)
    draw = ImageDraw.Draw(image)
    
    for pred in result.pred: 
        box = pred.boxes
        class_name = model.model.names[int(pred.cls)] 
        confidence = round(float(pred.conf), 2)
        
        draw.rectangle(box.tolist(), outline="red", width=3) 
        draw.text((box[0], box[1]), f"{class_name} {confidence}", fill="white") 

    output_path = os.path.join(output_folder, f"{filename.split('.')[0]}_{i}_detected.jpg") 
    image.save(output_path)

위 코드에서 model.model.names를 통해 클래스 이름을, pred.conf를 통해 각 바운딩 박스별 확률을 얻을 수 있습니다. 그리고 이 정보를 가지고 각 바운딩 박스 위에 텍스트를 출력할 수 있습니다.

none 값에 대한 오류는 pred 객체가 없는 경우(탐지가 안 된 경우)에 발생할 수 있습니다. 그래서 이 경우를 처리하기 위해 다음과 같이 코드를 추가로 수정할 수 있습니다:

if result.pred:
    # 위 코드 수행
else:
    print("No objects detected!") 

이렇게 pred 객체 유무를 확인한 후에 탐지 결과에 대한 처리를 진행하면 none 값으로 인한 오류를 방지할 수 있습니다.

제가 제시한 코드가 도움이 되었길 바랍니다. 혹시 추가로 궁금한 점이 있다면 주저 마시고 질문해 주세요. 최선을 다해 답변드리겠습니다.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!
  • 아래 답변은 OpenAI의 GPT-4 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요! 라즈베리파이4에서 YOLOv8을 사용하여 객체 탐지를 진행하고 계시는군요. 저장된 이미지에 클래스와 확률을 표시하는 부분에 어려움을 겪고 계신 것으로 이해했습니다. 문제 해결을 위해 최선을 다해 도와드리겠습니다.

YOLO 모델의 탐지 결과에는 바운딩 박스뿐만 아니라 클래스와 확률 정보도 포함되어 있습니다. 이 정보를 이미지에 표시하기 위해서는 results 객체에서 해당 정보를 추출하고, ImageDraw를 사용하여 이미지에 텍스트로 추가해야 합니다.

아래는 수정된 코드 예시입니다. 클래스와 확률을 이미지에 표시하는 부분을 추가했습니다.

import os
from ultralytics import YOLO
from PIL import Image, ImageDraw, ImageFont

model_path = '/home/yolo/best.pt'
model = YOLO(model_path)

input_folder = '/home/yolo/test'
output_folder = '/home/yolo/output'
os.makedirs(output_folder, exist_ok=True)

# 폰트 파일 경로 설정 (예: DejaVuSans-Bold.ttf)
font_path = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'
font_size = 16  # 원하는 폰트 크기로 조정
font = ImageFont.truetype(font_path, font_size)

for filename in os.listdir(input_folder):
    if filename.endswith(('.jpg', '.jpeg', '.png', '.bmp')):
        image_path = os.path.join(input_folder, filename)
        results = model(image_path)

        for i, result in enumerate(results):
            image = Image.open(image_path)
            draw = ImageDraw.Draw(image)
            for box, label, score in zip(result.boxes.xyxy, result.labels, result.scores):
                draw.rectangle(box.tolist(), outline="red", width=3)
                # 클래스와 확률 표시
                text = f"{label} {score:.2f}"
                draw.text((box[0], box[1]), text, fill="red", font=font)
            del draw

            output_path = os.path.join(output_folder, f"{filename.split('.')[0]}_{i}_detected.jpg")
            image.save(output_path)
            print(f"Saved detection result to {output_path}")

위 코드에서 font_path는 사용하고 있는 시스템에 설치된 폰트의 경로를 지정해야 합니다. 라즈베리파이에서 사용 가능한 폰트 경로를 찾아서 지정해주세요. 또한, font_size는 이미지에 표시될 텍스트의 크기를 조정할 수 있습니다.

이 코드는 각 탐지된 객체의 바운딩 박스 옆에 해당 객체의 클래스와 확률을 표시합니다. draw.text 함수는 텍스트를 이미지에 추가하는 데 사용됩니다.

참고하실 수 있는 PyTorch 공식 문서 링크를 아래에 첨부합니다:

제가 제공한 코드나 정보가 정확하지 않을 수도 있으니, 실행하시면서 문제가 발생하면 추가적인 질문을 해주시면 감사하겠습니다. 코드를 실행하시기 전에 필요한 폰트 파일이 시스템에 설치되어 있는지 확인하시고, 폰트 경로를 올바르게 설정하셔야 합니다. 도움이 되셨길 바랍니다!


  • 이 답변이 도움이 되셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!