젯슨나노 문의

Ultralytics YOLOv5 ??, AGPL-3.0 license

"""
Run YOLOv5 detection inference on images, videos, directories, globs, YouTube, webcam, streams, etc.

Usage - sources:
$ python detect.py --weights yolov5s.pt --source 0 # webcam
img.jpg # image
vid.mp4 # video
screen # screenshot
path/ # directory
list.txt # list of images
list.streams # list of streams
'path/*.jpg' # glob
'https://youtu.be/LNwODJXcvt4' # YouTube
'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream

Usage - formats:
$ python detect.py --weights yolov5s.pt # PyTorch
yolov5s.torchscript # TorchScript
yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn
yolov5s_openvino_model # OpenVINO
yolov5s.engine # TensorRT
yolov5s.mlmodel # CoreML (macOS-only)
yolov5s_saved_model # TensorFlow SavedModel
yolov5s.pb # TensorFlow GraphDef
yolov5s.tflite # TensorFlow Lite
yolov5s_edgetpu.tflite # TensorFlow Edge TPU
yolov5s_paddle_model # PaddlePaddle
"""

-- coding: utf-8 --

import argparse
import csv
import os
import platform
import sys
from pathlib import Path
from playsound import playsound
import torch

FILE = Path(file).resolve()
ROOT = FILE.parents[0] # YOLOv5 root directory
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT)) # add ROOT to PATH
ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative

from ultralytics.utils.plotting import Annotator, colors, save_one_box
from models.common import DetectMultiBackend
from utils.dataloaders import IMG_FORMATS, VID_FORMATS, LoadImages, LoadScreenshots, LoadStreams
from utils.general import (
LOGGER, Profile, check_file, check_img_size, check_imshow, check_requirements, colorstr, cv2,
increment_path, non_max_suppression, print_args, scale_boxes, strip_optimizer, xyxy2xywh
)
from utils.torch_utils import select_device, smart_inference_mode

@smart_inference_mode()
def run(
weights=ROOT / "best.pt", # model path or triton URL
source=ROOT / "data/images", # file/dir/URL/glob/screen/0(webcam)
data=ROOT / "data/coco128.yaml", # dataset.yaml path
imgsz=(320, 320), # inference size (height, width)
conf_thres=0.25, # confidence threshold
iou_thres=0.45, # NMS IOU threshold
max_det=1000, # maximum detections per image
device="", # cuda device, i.e. 0 or 0,1,2,3 or cpu
view_img=False, # show results
save_txt=False, # save results to *.txt
save_csv=False, # save results in CSV format
save_conf=False, # save confidences in --save-txt labels
save_crop=False, # save cropped prediction boxes
nosave=False, # do not save images/videos
classes=None, # filter by class: --class 0, or --class 0 2 3
agnostic_nms=False, # class-agnostic NMS
augment=False, # augmented inference
visualize=False, # visualize features
update=False, # update all models
project=ROOT / "runs/detect", # save results to project/name
name="exp", # save results to project/name
exist_ok=False, # existing project/name ok, do not increment
line_thickness=3, # bounding box thickness (pixels)
hide_labels=False, # hide labels
hide_conf=False, # hide confidences
half=False, # use FP16 half-precision inference
dnn=False, # use OpenCV DNN for ONNX inference
vid_stride=2, # video frame-rate stride
):
"""
Runs YOLOv5 detection inference on various sources like images, videos, directories, streams, etc.

Args:
    weights (str | Path): Path to the model weights file or a Triton URL. Default is 'yolov5s.pt'.
    source (str | Path): Input source, which can be a file, directory, URL, glob pattern, screen capture, or webcam index.
        Default is 'data/images'.
    data (str | Path): Path to the dataset YAML file. Default is 'data/coco128.yaml'.
    imgsz (tuple[int, int]): Inference image size as a tuple (height, width). Default is (640, 640).
    conf_thres (float): Confidence threshold for detections. Default is 0.25.
    iou_thres (float): Intersection Over Union (IOU) threshold for non-max suppression. Default is 0.45.
    max_det (int): Maximum number of detections per image. Default is 1000.
    device (str): CUDA device identifier (e.g., '0' or '0,1,2,3') or 'cpu'. Default is an empty string, which
        uses the best available device.
    view_img (bool): If True, display inference results using OpenCV. Default is False.
    save_txt (bool): If True, save results in a text file. Default is False.
    save_csv (bool): If True, save results in a CSV file. Default is False.
    save_conf (bool): If True, include confidence scores in the saved results. Default is False.
    save_crop (bool): If True, save cropped prediction boxes. Default is False.
    nosave (bool): If True, do not save inference images or videos. Default is False.
    classes (list[int]): List of class indices to filter detections by. Default is None.
    agnostic_nms (bool): If True, perform class-agnostic non-max suppression. Default is False.
    augment (bool): If True, use augmented inference. Default is False.
    visualize (bool): If True, visualize feature maps. Default is False.
    update (bool): If True, update all models' weights. Default is False.
    project (str | Path): Directory to save results. Default is 'runs/detect'.
    name (str): Name of the current experiment; used to create a subdirectory within 'project'. Default is 'exp'.
    exist_ok (bool): If True, existing directories with the same name are reused instead of being incremented. Default is
        False.
    line_thickness (int): Thickness of bounding box lines in pixels. Default is 3.
    hide_labels (bool): If True, do not display labels on bounding boxes. Default is False.
    hide_conf (bool): If True, do not display confidence scores on bounding boxes. Default is False.
    half (bool): If True, use FP16 half-precision inference. Default is False.
    dnn (bool): If True, use OpenCV DNN backend for ONNX inference. Default is False.
    vid_stride (int): Stride for processing video frames, to skip frames between processing. Default is 1.

Returns:
    None

Examples:
```python
from ultralytics import run

# Run inference on an image
run(source='data/images/example.jpg', weights='yolov5s.pt', device='0')

# Run inference on a video with specific confidence threshold
run(source='data/videos/example.mp4', weights='yolov5s.pt', conf_thres=0.4, device='0')
```
"""
source = str(source)
save_img = not nosave and not source.endswith(".txt")  # save inference images
is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
is_url = source.lower().startswith(("rtsp://", "rtmp://", "http://", "https://"))
webcam = source.isnumeric() or source.endswith(".streams") or (is_url and not is_file)
screenshot = source.lower().startswith("screen")
if is_url and is_file:
    source = check_file(source)  # download

# Directories
save_dir = increment_path(Path(project) / name, exist_ok=exist_ok)  # increment run
(save_dir / "labels" if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir

# Load model
device = select_device(device)
model = DetectMultiBackend(weights, device=device, dnn=dnn, data=data, fp16=half)
stride, names, pt = model.stride, model.names, model.pt
model.names = names if isinstance(names, list) else names.names if hasattr(names, "names") else []

# Dataloader
dataset = LoadImages(source, img_size=imgsz, stride=int(stride), auto=webcam or screenshot)
dataset = LoadScreenshots(source, img_size=imgsz, stride=int(stride), auto=webcam or screenshot) if screenshot else dataset
dataset = LoadStreams(str(source), img_size=imgsz, stride=int(stride), auto=webcam or screenshot) if webcam else dataset

# Run inference
if pt and not update:
    if visualize:
        model.visualize = True
    results, times = Profile(model.run, args=(dataset,), kwargs={'conf_thres': conf_thres, 'iou_thres': iou_thres, 'max_det': max_det})
else:
    if visualize:
        raise TypeError('Visualizing is not supported for this model')
    results, times = Profile(model.run, args=(dataset,), kwargs={'conf_thres': conf_thres, 'iou_thres': iou_thres, 'max_det': max_det})
    if update:
        strip_optimizer(weights)  # update model (to fix SourceChangeWarning)

# Process results
for path, out, imgsz in zip(dataset.paths, results.xywh, dataset.img_size):
    labels = []
    for *box, conf, cls in out.tolist():
        if save_txt or save_img or save_crop:  # Write to file
            xywh = xyxy2xywh(box)  # xyxy to xywh
            xywh[2:] *= imgsz  # normalized to pixel space
            line = (cls, *xywh, conf) if save_conf else (cls, *xywh)  # label format
            labels.append(f"{cls} {xywh[0]:g} {xywh[1]:g} {xywh[2]:g} {xywh[3]:g} {conf:g}\n")
            if save_crop:
                save_one_box(xywh, Path(path).with_suffix('.jpg'), None, line_thickness=line_thickness)
            if save_img:
                save_one_box(xywh, Path(str(save_dir) + Path(path).name), None, line_thickness=line_thickness)
            if save_conf:
                with open(Path(save_dir) / 'labels' / Path(path).stem + '.txt', 'a') as file:
                    file.write(labels)
        if view_img:  # Add bbox to image
            save_one_box(xywh, path, names[int(cls)], line_thickness=line_thickness, hide_labels=hide_labels, hide_conf=hide_conf)
    if view_img:
        Annotator(path, line_thickness=line_thickness).save()

# Display results
for path, img, det, im0s in zip(dataset.paths, dataset.imgs, results.xywh, dataset.im0s):
    for *box, conf, cls in det.tolist():
        label = None if hide_labels else (names[int(cls)], conf) if hide_conf else (f'{names[int(cls)]} {conf:.2f}')
        plot_one_box(box, img, color=colors(int(cls)), label=label, line_thickness=line_thickness)
    cv2.imshow(imgsz, im0s)

# Save results (image with detections)
if save_img:
    LOGGER.info(f'Saving results to {str(save_dir)}')
if save_txt or save_csv:
    LOGGER.info('Saving labels')
    with open(save_dir / 'labels.txt', 'w') as file:
        for img, lines in zip(dataset.imgs, results.xywh):
            file.write(f"{img}: {lines}\n")
if save_csv:
    LOGGER.info('Converting labels to CSV format')
    with open(save_dir / 'labels.csv', 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(['image_id', 'prediction'])
        for img, lines in zip(dataset.imgs, results.xywh):
            writer.writerow([img, lines])

# Play sound
if str(weights).endswith('.tflite'):
    LOGGER.info('Detect sound')
    playsound('gun.wav')

# Print results
for i, (path, out, imgsz, im0s) in enumerate(zip(dataset.paths, results.xywh, dataset.img_size, dataset.im0s)):
    LOGGER.info(f'{i + 1}/{len(dataset)}: {path.stem} ({im0s.shape[1]}x{im0s.shape[0]}) {len(out)} detections, {times[i]:.3f} s')

def parse_opt():
"""
Parses command-line arguments for YOLOv5 detection, setting inference options and model configurations.

Args:
    --weights (str | list[str], optional): Model path or Triton URL. Defaults to ROOT / 'yolov5s.pt'.
    --source (str, optional): File/dir/URL/glob/screen/0(webcam). Defaults to ROOT / 'data/images'.
    --data (str, optional): Dataset YAML path. Provides dataset configuration information.
    --imgsz (list[int], optional): Inference size (height, width). Defaults to [640].
    --conf-thres (float, optional): Confidence threshold. Defaults to 0.25.
    --iou-thres (float, optional): NMS IoU threshold. Defaults to 0.45.
    --max-det (int, optional): Maximum number of detections per image. Defaults to 1000.
    --device (str, optional): CUDA device, i.e., '0' or '0,1,2,3' or 'cpu'. Defaults to "".
    --view-img (bool, optional): Flag to display results. Defaults to False.
    --save-txt (bool, optional): Flag to save results to *.txt files. Defaults to False.
    --save-csv (bool, optional): Flag to save results in CSV format. Defaults to False.
    --save-conf (bool, optional): Flag to save confidences in labels saved via --save-txt. Defaults to False.
    --save-crop (bool, optional): Flag to save cropped prediction boxes. Defaults to False.
    --nosave (bool, optional): Flag to prevent saving images/videos. Defaults to False.
    --classes (list[int], optional): List of classes to filter results by, e.g., '--classes 0 2 3'. Defaults to None.
    --agnostic-nms (bool, optional): Flag for class-agnostic NMS. Defaults to False.
    --augment (bool, optional): Flag for augmented inference. Defaults to False.
    --visualize (bool, optional): Flag for visualizing features. Defaults to False.
    --update (bool, optional): Flag to update all models in the model directory. Defaults to False.
    --project (str, optional): Directory to save results. Defaults to ROOT / 'runs/detect'.
    --name (str, optional): Sub-directory name for saving results within --project. Defaults to 'exp'.
    --exist-ok (bool, optional): Flag to allow overwriting if the project/name already exists. Defaults to False.
    --line-thickness (int, optional): Thickness (in pixels) of bounding boxes. Defaults to 3.
    --hide-labels (bool, optional): Flag to hide labels in the output. Defaults to False.
    --hide-conf (bool, optional): Flag to hide confidences in the output. Defaults to False.
    --half (bool, optional): Flag to use FP16 half-precision inference. Defaults to False.
    --dnn (bool, optional): Flag to use OpenCV DNN for ONNX inference. Defaults to False.
    --vid-stride (int, optional): Video frame-rate stride, determining the number of frames to skip in between consecutive frames. Defaults to 1.

Returns:
    argparse.Namespace: Parsed command-line arguments as an argparse.Namespace object.

Example:
    ```python
    from ultralytics import YOLOv5
    args = YOLOv5.parse_opt()
    ```
"""
parser = argparse.ArgumentParser()
parser.add_argument("--weights", nargs="+", type=str, default=ROOT / "yolov5s.pt", help="model path or triton URL")
parser.add_argument("--source", type=str, default=ROOT / "data/images", help="file/dir/URL/glob/screen/0(webcam)")
parser.add_argument("--data", type=str, default=ROOT / "data/coco128.yaml", help="(optional) dataset.yaml path")
parser.add_argument("--imgsz", "--img", "--img-size", nargs="+", type=int, default=[640], help="inference size h,w")
parser.add_argument("--conf-thres", type=float, default=0.25, help="confidence threshold")
parser.add_argument("--iou-thres", type=float, default=0.45, help="NMS IoU threshold")
parser.add_argument("--max-det", type=int, default=1000, help="maximum detections per image")
parser.add_argument("--device", default="", help="cuda device, i.e. 0 or 0,1,2,3 or cpu")
parser.add_argument("--view-img", action="store_true", help="show results")
parser.add_argument("--save-txt", action="store_true", help="save results to *.txt")
parser.add_argument("--save-csv", action="store_true", help="save results in CSV format")
parser.add_argument("--save-conf", action="store_true", help="save confidences in --save-txt labels")
parser.add_argument("--save-crop", action="store_true", help="save cropped prediction boxes")
parser.add_argument("--nosave", action="store_true", help="do not save images/videos")
parser.add_argument("--classes", nargs="+", type=int, help="filter by class: --classes 0, or --classes 0 2 3")
parser.add_argument("--agnostic-nms", action="store_true", help="class-agnostic NMS")
parser.add_argument("--augment", action="store_true", help="augmented inference")
parser.add_argument("--visualize", action="store_true", help="visualize features")
parser.add_argument("--update", action="store_true", help="update all models")
parser.add_argument("--project", default=ROOT / "runs/detect", help="save results to project/name")
parser.add_argument("--name", default="exp", help="save results to project/name")
parser.add_argument("--exist-ok", action="store_true", help="existing project/name ok, do not increment")
parser.add_argument("--line-thickness", default=3, type=int, help="bounding box thickness (pixels)")
parser.add_argument("--hide-labels", default=False, action="store_true", help="hide labels")
parser.add_argument("--hide-conf", default=False, action="store_true", help="hide confidences")
parser.add_argument("--half", action="store_true", help="use FP16 half-precision inference")
parser.add_argument("--dnn", action="store_true", help="use OpenCV DNN for ONNX inference")
parser.add_argument("--vid-stride", type=int, default=1, help="video frame-rate stride")
opt = parser.parse_args()
opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1  # expand
print_args(vars(opt))
return opt

def main(opt):
"""
Executes YOLOv5 model inference based on provided command-line arguments, validating dependencies before running.

Args:
    opt (argparse.Namespace): Command-line arguments for YOLOv5 detection. See function `parse_opt` for details.

Returns:
    None

Note:
    This function performs essential pre-execution checks and initiates the YOLOv5 detection process based on user-specified options.
    Refer to the usage guide and examples for more information about different sources and formats at:
    https://github.com/ultralytics/ultralytics

Example usage:

```python
if __name__ == "__main__":
    opt = parse_opt()
    main(opt)
```
"""
check_requirements(ROOT / "requirements.txt", exclude=("tensorboard", "thop"))
run(**vars(opt))

if name == "main":
opt = parse_opt()
main(opt)
이게 젯슨나노에서 yolov5를 통해 객체탐지를 하고 실시간으로 웹캠으로 보여지게 하는데 객체 탐지되면 audio.mp3를 통해 소리를 나게 하였습니다 근데 에러코드로 user@user:~/yolov5$ python3.8 detect.py --source 0 --weights best.pt --imgsz 320
detect: weights=['best.pt'], source=0, data=data/coco128.yaml, imgsz=[320, 320],txt=False, save_csv=False, save_conf=False, save_crop=False, nosave=False, classject=runs/detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False,
YOLOv5 :rocket: v7.0-339-g150a1a31 Python-3.8.12 torch-2.3.1 CPU

Fusing layers...
YOLOv5s summary: 157 layers, 7018216 parameters, 0 gradients, 15.8 GFLOPs
Traceback (most recent call last):
File "detect.py", line 335, in
main(opt)
File "detect.py", line 330, in main
run(**vars(opt))
File "/home/user/.local/lib/python3.8/site-packages/torch/utils/_contextlib.py
return func(*args, **kwargs)
File "detect.py", line 158, in run
dataset = LoadImages(source, img_size=imgsz, stride=int(stride), auto=webcam
File "/home/user/yolov5/utils/dataloaders.py", line 335, in init
raise FileNotFoundError(f"{p} does not exist")
FileNotFoundError: /home/user/yolov5/0 does not exist
이렇게 뜨는데 어떻게 해결해야되나요 mp3코드를 추가하기전까지는 웹캠이 작동되었습니다

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

안녕하세요! 젯슨나노에서 YOLOv5를 사용하여 객체 탐지를 하고, 탐지가 되면 audio.mp3를 재생하는 과정에서 발생한 문제에 대해 질문해주셨군요. 에러 메시지를 보니 웹캠을 사용하는 과정에서 파일을 찾을 수 없다는 FileNotFoundError가 발생한 것 같습니다. 이 문제를 함께 해결해보도록 하겠습니다.

문제 정리

  • 젯슨나노에서 YOLOv5를 사용하여 웹캠으로 실시간 객체 탐지를 시도하고 있습니다.
  • 객체가 탐지되면 audio.mp3 파일을 재생하도록 설정하였습니다.
  • mp3 파일 재생 코드를 추가하기 전까지는 웹캠이 정상적으로 작동하였습니다.
  • 현재는 FileNotFoundError: /home/user/yolov5/0 does not exist 에러가 발생하고 있습니다.

해결 방안

에러 메시지를 통해 볼 때, 웹캠을 사용하는 과정에서 경로 문제가 발생한 것으로 보입니다. 웹캠의 소스를 지정할 때, 숫자 0을 사용하는데, 이것이 파일 경로로 잘못 인식되어 발생한 문제로 추정됩니다. 이를 해결하기 위해 몇 가지 점검 및 수정 방안을 제안드립니다.

  1. 웹캠 소스 지정 확인: 웹캠을 지정할 때는 일반적으로 --source 0과 같이 사용합니다. 이 부분이 올바르게 설정되었는지 확인해주세요.

  2. playsound 사용 시 경로 문제: playsound 라이브러리를 사용하여 audio.mp3를 재생하는 코드 부분에서 경로 문제가 발생하지 않았는지 확인해주세요. 경로가 올바르게 설정되어 있는지, 해당 파일이 실제로 존재하는지 확인이 필요합니다.

  3. 코드 실행 환경 점검: detect.py 스크립트를 실행하는 현재 디렉토리가 올바른지 확인해주세요. YOLOv5 관련 파일들이 있는 디렉토리에서 스크립트를 실행해야 합니다.

  4. playsound 대신 다른 방법 고려: playsound 대신 PyTorch와 호환되는 다른 방법으로 소리를 재생해보는 것도 하나의 방법입니다. 예를 들어, simpleaudiopygame 라이브러리를 사용하는 방법이 있습니다.

예제 코드

웹캠 소스를 올바르게 지정하는 기본 예제 코드는 다음과 같습니다.

# YOLOv5 웹캠 실행 예제
# detect.py 스크립트에 대한 기본 사용 방법
python detect.py --source 0 --weights best.pt --imgsz 320

playsound를 사용하여 소리를 재생하는 부분은 다음과 같이 구현할 수 있습니다. 단, 파일 경로가 올바른지 확인해야 합니다.

from playsound import playsound

# audio.mp3 파일 재생
playsound('/path/to/audio.mp3')

추가 자료

YOLOv5 사용법 및 예제 코드에 대한 더 자세한 정보는 공식 문서를 참조하시기 바랍니다.

제가 제안드린 해결 방안이 정확하지 않을 수도 있으니, 문제가 계속되면 추가적인 정보와 함께 다시 질문해주시기 바랍니다. 문제 해결을 위해 최선을 다하겠습니다.


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

안녕하세요. 제시한 오류를 살펴보면 detect.py 파일에서 330번째 줄에서 run() 함수를 호출할 때 인자로 **vars(opt)``를 전달하고 있습니다. 이 인자는 opt객체의 모든 속성을 키워드 인자로 펼쳐run()함수에 전달합니다.run()함수에서dataset = LoadImages(source, img_size=imgsz, stride=int(stride), auto=webcam)코드에서source` 인자로 0을 전달했는데, 이는 웹캠을 나타냅니다. 하지만 FileNotFoundError가 발생하여 '/home/user/yolov5/0'이 존재하지 않는다고 알려줍니다.

이 오류를 해결하려면 웹캠 장치가 올바르게 구성되었는지 확인해야 합니다. 사용 중인 카메라가 컴퓨터에 연결되어 있고 v4l2-ctl --list-devices 명령을 사용하여 인식되고 있는지 확인할 수 있습니다. 또한 사용 중인 카메라 드라이버가 최신인지 확인하는 것도 좋습니다.

오류가 지속되면 detect.py 파일에서 330번째 줄의 코드를 다음과 같이 수정해 보세요.

dataset = LoadImages(str(source), img_size=imgsz, stride=int(stride), auto=webcam)

이렇게 하면 source 인자가 문자열로 캐스팅되므로 LoadImages 클래스의 생성자가 올바르게 호출됩니다.


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

안녕하세요 dkdwkim15님, YOLOv5를 젯슨 나노에서 실행하면서 웹캠을 통해 객체 탐지 결과를 보여주고 탐지시 소리를 내려고 하시는데 문제가 발생한 것 같네요.

우선 에러 메시지를 보면 "FileNotFoundError: /home/user/yolov5/0 does not exist" 라고 뜨는 걸 보니 detect.py를 실행할 때 "--source 0" 으로 웹캠을 지정했는데, 스크립트에서는 이를 파일 경로로 인식해 "/home/user/yolov5/0" 경로를 찾으려다 실패한 것으로 보입니다.

이 문제를 해결하려면 다음과 같이 해볼 수 있겠습니다:

  1. 웹캠 인덱스를 정수형으로 명시적 변환
    LoadImages() 함수에서 source가 정수형 웹캠 인덱스인 경우 str(source)로 문자열 변환하기 전에 int(source)로 명시적 정수 변환을 해주는 것이 좋겠습니다. 이렇게 하면 웹캠 인덱스가 의도치 않게 파일경로로 해석되는 것을 막을 수 있습니다.
# utils/dataloaders.py 파일의 LoadImages 클래스 생성자 수정 
def __init__(...):
    ...
    if webcam:
        source = int(source)  # 웹캠 인덱스 정수 변환
    ...
  1. playsound 모듈 설치 확인
    mp3 재생에 사용한 playsound 모듈이 설치되어 있는지 확인해 보시기 바랍니다. 없다면 다음 명령으로 설치할 수 있습니다.
pip install playsound
  1. mp3 파일 경로 확인
    detectpy에서 탐지시 재생하려는 mp3 파일('gun.wav')의 경로가 detect.py 파일 위치에 있는지 확인해 주세요. 다른 경로에 있다면 해당 경로를 지정해 주어야 합니다.

  2. 권한 문제 확인
    젯슨 나노에서 웹캠, 오디오 등 하드웨어 자원에 액세스할 권한이 있는지 확인해 보시기 바랍니다. 필요시 sudo를 사용하거나 해당 그룹에 사용자를 추가하는 방법으로 해결할 수 있습니다.

마지막으로 공식 YOLOv5 저장소의 이슈들을 검색해 보시면 비슷한 문제에 대한 해결책을 찾을 수도 있을 것 같네요.

추가로 도움이 필요하거나 다른 문제가 있다면 말씀해 주세요. 해결되기를 바랍니다!


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

안녕하세요! 젯슨 나노에서 YOLOv5를 사용하여 객체 탐지를 하고, 웹캠을 통해 실시간으로 결과를 보여주며, 객체가 탐지되면 소리를 재생하려고 하시는군요. 에러 메시지를 보니 파일 경로와 관련된 문제로 보입니다. 문제를 해결하기 위해 몇 가지 확인해볼 사항을 안내드리겠습니다.

문제 요약

  • YOLOv5를 사용하여 객체 탐지를 수행하고, 웹캠을 통해 실시간으로 결과를 보여주며, 객체가 탐지되면 소리를 재생하려고 함.
  • FileNotFoundError: /home/user/yolov5/0 does not exist 에러 발생.
  • mp3 코드를 추가하기 전까지는 웹캠이 정상 작동했음.

해결 방법

  1. 경로 확인: source=0은 웹캠을 의미합니다. 하지만 경로가 잘못 설정되어 있을 수 있습니다. detect.py 파일에서 source 변수를 확인하고, 웹캠 인덱스가 제대로 설정되어 있는지 확인하세요.

  2. 코드 수정: detect.py 파일에서 source 변수를 올바르게 설정하고, 웹캠 인덱스를 명확히 지정해보세요.

  3. MP3 코드 확인: MP3 재생 코드를 추가한 부분이 웹캠 경로 설정에 영향을 미쳤을 가능성이 있습니다. MP3 재생 코드가 다른 부분에 영향을 미치지 않도록 확인하세요.

예제 코드

아래는 YOLOv5를 사용하여 웹캠을 통해 객체 탐지를 수행하고, 객체가 탐지되면 소리를 재생하는 예제 코드입니다.

import argparse
import os
import sys
from pathlib import Path
from playsound import playsound
import torch
from models.common import DetectMultiBackend
from utils.dataloaders import LoadImages, LoadStreams
from utils.general import (check_img_size, non_max_suppression, scale_boxes, xyxy2xywh)
from utils.torch_utils import select_device

def run(weights='best.pt', source='0', imgsz=(320, 320), conf_thres=0.25, iou_thres=0.45, device='', view_img=False):
    source = str(source)
    is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
    webcam = source.isnumeric() or source.endswith('.streams')

    # Load model
    device = select_device(device)
    model = DetectMultiBackend(weights, device=device)
    stride, names = model.stride, model.names

    # Dataloader
    if webcam:
        dataset = LoadStreams(source, img_size=imgsz, stride=stride)
    else:
        dataset = LoadImages(source, img_size=imgsz, stride=stride)

    # Run inference
    for path, img, im0s, vid_cap in dataset:
        img = torch.from_numpy(img).to(device)
        img = img.float() / 255.0
        if img.ndimension() == 3:
            img = img.unsqueeze(0)

        # Inference
        pred = model(img, augment=False, visualize=False)

        # Apply NMS
        pred = non_max_suppression(pred, conf_thres, iou_thres, classes=None, agnostic=False)

        # Process detections
        for i, det in enumerate(pred):
            if len(det):
                playsound('audio.mp3')  # Play sound when object is detected

                # Rescale boxes from img_size to im0 size
                det[:, :4] = scale_boxes(img.shape[2:], det[:, :4], im0s.shape).round()

                # Print results
                for *xyxy, conf, cls in det:
                    print(f'Detected {names[int(cls)]} with confidence {conf:.2f}')

                # Show results
                if view_img:
                    cv2.imshow(str(path), im0s)
                    if cv2.waitKey(1) == ord('q'):
                        raise StopIteration

def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='best.pt', help='model path')
    parser.add_argument('--source', type=str, default='0', help='source')  # webcam index
    parser.add_argument('--imgsz', type=int, default=320, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='display results')
    opt = parser.parse_args()
    return opt

def main(opt):
    run(**vars(opt))

if __name__ == "__main__":
    opt = parse_opt()
    main(opt)

참고 자료

이 코드가 도움이 되길 바랍니다. 문제가 계속 발생하면 추가 정보를 제공해주시면 더 자세히 도와드리겠습니다. 감사합니다!


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