์ฝ˜ํ…์ธ ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๊ณ ๊ธ‰ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”: Ultralytics YOLOv8 ๐Ÿš€์„ ์‚ฌ์šฉํ•œ ํžˆํŠธ๋งต

ํžˆํŠธ๋งต ์†Œ๊ฐœ

๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑํ•œ ํžˆํŠธ๋งต์€ Ultralytics YOLOv8 ๋กœ ์ƒ์„ฑ๋œ ํžˆํŠธ๋งต์€ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์ƒํ•œ ์ƒ‰์ƒ์œผ๋กœ ๊ตฌ๋ถ„๋œ ๋งคํŠธ๋ฆญ์Šค๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ๊ฐ์  ๋„๊ตฌ๋Š” ๋‹ค์–‘ํ•œ ์ƒ‰์ƒ ์ŠคํŽ™ํŠธ๋Ÿผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๋”ฐ๋œปํ•œ ์ƒ‰์กฐ๋Š” ๋” ๋†’์€ ๊ฐ•๋„๋ฅผ, ์ฐจ๊ฐ€์šด ์ƒ‰์กฐ๋Š” ๋” ๋‚ฎ์€ ๊ฐ’์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ํžˆํŠธ๋งต์€ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ํŒจํ„ด, ์ƒ๊ด€๊ด€๊ณ„, ์ด์ƒ ์ง•ํ›„๋ฅผ ์‹œ๊ฐํ™”ํ•˜๋Š” ๋ฐ ํƒ์›”ํ•˜๋ฉฐ, ๋‹ค์–‘ํ•œ ์˜์—ญ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋Š” ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ณ  ๋งค๋ ฅ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.



Watch: ํžˆํŠธ๋งต์„ ์‚ฌ์šฉํ•œ Ultralytics YOLOv8

๋ฐ์ดํ„ฐ ๋ถ„์„์— ํžˆํŠธ๋งต์„ ์„ ํƒํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ์ง๊ด€์ ์ธ ๋ฐ์ดํ„ฐ ๋ถ„ํฌ ์‹œ๊ฐํ™”: ํžˆํŠธ๋งต์€ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์‹œ๊ฐ์  ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ์ง‘์ค‘๋„์™€ ๋ถ„ํฌ๋ฅผ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
  • ํšจ์œจ์ ์ธ ํŒจํ„ด ํƒ์ง€: ๋ฐ์ดํ„ฐ๋ฅผ ํžˆํŠธ๋งต ํ˜•์‹์œผ๋กœ ์‹œ๊ฐํ™”ํ•˜๋ฉด ์ถ”์„ธ, ๊ตฐ์ง‘, ์ด์ƒ๊ฐ’์„ ๋” ์‰ฝ๊ฒŒ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์–ด ๋ถ„์„๊ณผ ์ธ์‚ฌ์ดํŠธ ๋„์ถœ์ด ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ํ–ฅ์ƒ๋œ ๊ณต๊ฐ„ ๋ถ„์„ ๋ฐ ์˜์‚ฌ ๊ฒฐ์ •: ํžˆํŠธ๋งต์€ ๊ณต๊ฐ„ ๊ด€๊ณ„๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋ฉฐ ๋น„์ฆˆ๋‹ˆ์Šค ์ธํ…”๋ฆฌ์ „์Šค, ํ™˜๊ฒฝ ์—ฐ๊ตฌ, ๋„์‹œ ๊ณ„ํš๊ณผ ๊ฐ™์€ ๋ถ„์•ผ์˜ ์˜์‚ฌ ๊ฒฐ์ • ํ”„๋กœ์„ธ์Šค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

๊ตํ†ตํŽธ ๋ฆฌํ…Œ์ผ
Ultralytics YOLOv8 ์šด์†ก ํžˆํŠธ๋งต Ultralytics YOLOv8 ๋ฆฌํ…Œ์ผ ํžˆํŠธ๋งต
Ultralytics YOLOv8 ์šด์†ก ํžˆํŠธ๋งต Ultralytics YOLOv8 ๋ฆฌํ…Œ์ผ ํžˆํŠธ๋งต

ํžˆํŠธ๋งต ๊ตฌ์„ฑ

  • heatmap_alpha: ์ด ๊ฐ’์ด ๋ฒ”์œ„(0.0 - 1.0) ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • decay_factor: ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋” ์ด์ƒ ํ”„๋ ˆ์ž„์— ์—†์„ ๋•Œ ํžˆํŠธ๋งต์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ, ๊ฐ’์€ (0.0 - 1.0) ๋ฒ”์œ„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Ultralytics YOLOv8 ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•œ ํžˆํŠธ๋งต

from ultralytics import YOLO
from ultralytics.solutions import heatmap
import cv2

model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("path/to/video/file.mp4")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))

# Video writer
video_writer = cv2.VideoWriter("heatmap_output.avi",
                               cv2.VideoWriter_fourcc(*'mp4v'),
                               fps,
                               (w, h))

# Init heatmap
heatmap_obj = heatmap.Heatmap()
heatmap_obj.set_args(colormap=cv2.COLORMAP_PARULA,
                     imw=w,
                     imh=h,
                     view_img=True,
                     shape="circle")

while cap.isOpened():
    success, im0 = cap.read()
    if not success:
        print("Video frame is empty or video processing has been successfully completed.")
        break
    tracks = model.track(im0, persist=True, show=False)

    im0 = heatmap_obj.generate_heatmap(im0, tracks)
    video_writer.write(im0)

cap.release()
video_writer.release()
cv2.destroyAllWindows()
from ultralytics import YOLO
from ultralytics.solutions import heatmap
import cv2

model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("path/to/video/file.mp4")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))

# Video writer
video_writer = cv2.VideoWriter("heatmap_output.avi",
                               cv2.VideoWriter_fourcc(*'mp4v'),
                               fps,
                               (w, h))

line_points = [(20, 400), (1080, 404)]  # line for object counting

# Init heatmap
heatmap_obj = heatmap.Heatmap()
heatmap_obj.set_args(colormap=cv2.COLORMAP_PARULA,
                     imw=w,
                     imh=h,
                     view_img=True,
                     shape="circle",
                     count_reg_pts=line_points)

while cap.isOpened():
    success, im0 = cap.read()
    if not success:
        print("Video frame is empty or video processing has been successfully completed.")
        break
    tracks = model.track(im0, persist=True, show=False)

    im0 = heatmap_obj.generate_heatmap(im0, tracks)
    video_writer.write(im0)

cap.release()
video_writer.release()
cv2.destroyAllWindows()
from ultralytics import YOLO
from ultralytics.solutions import heatmap
import cv2

model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("path/to/video/file.mp4")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))

# Video writer
video_writer = cv2.VideoWriter("heatmap_output.avi",
                               cv2.VideoWriter_fourcc(*'mp4v'),
                               fps,
                               (w, h))

# Define region points
region_points = [(20, 400), (1080, 404), (1080, 360), (20, 360)]

# Init heatmap
heatmap_obj = heatmap.Heatmap()
heatmap_obj.set_args(colormap=cv2.COLORMAP_PARULA,
                     imw=w,
                     imh=h,
                     view_img=True,
                     shape="circle",
                     count_reg_pts=region_points)

while cap.isOpened():
    success, im0 = cap.read()
    if not success:
        print("Video frame is empty or video processing has been successfully completed.")
        break
    tracks = model.track(im0, persist=True, show=False)

    im0 = heatmap_obj.generate_heatmap(im0, tracks)
    video_writer.write(im0)

cap.release()
video_writer.release()
cv2.destroyAllWindows()
from ultralytics import YOLO
from ultralytics.solutions import heatmap
import cv2

model = YOLO("yolov8s.pt")   # YOLOv8 custom/pretrained model

im0 = cv2.imread("path/to/image.png")  # path to image file
h, w = im0.shape[:2]  # image height and width

# Heatmap Init
heatmap_obj = heatmap.Heatmap()
heatmap_obj.set_args(colormap=cv2.COLORMAP_PARULA,
                     imw=w,
                     imh=h,
                     view_img=True,
                     shape="circle")

results = model.track(im0, persist=True)
im0 = heatmap_obj.generate_heatmap(im0, tracks=results)
cv2.imwrite("ultralytics_output.png", im0)
from ultralytics import YOLO
from ultralytics.solutions import heatmap
import cv2

model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("path/to/video/file.mp4")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))

# Video writer
video_writer = cv2.VideoWriter("heatmap_output.avi",
                               cv2.VideoWriter_fourcc(*'mp4v'),
                               fps,
                               (w, h))

classes_for_heatmap = [0, 2]  # classes for heatmap

# Init heatmap
heatmap_obj = heatmap.Heatmap()
heatmap_obj.set_args(colormap=cv2.COLORMAP_PARULA,
                     imw=w,
                     imh=h,
                     view_img=True,
                     shape="circle")

while cap.isOpened():
    success, im0 = cap.read()
    if not success:
        print("Video frame is empty or video processing has been successfully completed.")
        break
    tracks = model.track(im0, persist=True, show=False,
                         classes=classes_for_heatmap)

    im0 = heatmap_obj.generate_heatmap(im0, tracks)
    video_writer.write(im0)

cap.release()
video_writer.release()
cv2.destroyAllWindows()

์ธ์ˆ˜ set_args

์ด๋ฆ„ ์œ ํ˜• ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
view_img bool False ํžˆํŠธ๋งต์œผ๋กœ ํ”„๋ ˆ์ž„ ํ‘œ์‹œ
colormap cv2.COLORMAP None ํžˆํŠธ๋งต์šฉ cv2.COLORMAP
imw int None ํžˆํŠธ๋งต ๋„ˆ๋น„
imh int None ํžˆํŠธ๋งต ๋†’์ด
heatmap_alpha float 0.5 ํžˆํŠธ๋งต ์•ŒํŒŒ ๊ฐ’
count_reg_pts list None ๊ฐ์ฒด ๊ณ„์‚ฐ ์˜์—ญ ํฌ์ธํŠธ
count_txt_thickness int 2 ๊ฐ’ ํ…์ŠคํŠธ ํฌ๊ธฐ ๊ณ„์‚ฐ
count_txt_color RGB Color (0, 0, 0) ๊ฐœ์ฒด ์นด์šดํŠธ ํ…์ŠคํŠธ์˜ ์ „๊ฒฝ์ƒ‰
count_color RGB Color (255, 255, 255) ๊ฐœ์ฒด ์นด์šดํŠธ ํ…์ŠคํŠธ์˜ ๋ฐฐ๊ฒฝ์ƒ‰
count_reg_color RGB Color (255, 0, 255) ๊ณ„์‚ฐ ์˜์—ญ ์ƒ‰์ƒ
region_thickness int 5 ์˜์—ญ ๋‘๊ป˜ ๊ฐ’ ๊ณ„์‚ฐ
decay_factor float 0.99 ํŠน์ • ์‹œ๊ฐ„ ํ›„ ํžˆํŠธ๋งต ์˜์—ญ ์ œ๊ฑฐ๋ฅผ ์œ„ํ•œ ๊ฐ์‡  ๊ณ„์ˆ˜
shape str circle "์ง์‚ฌ๊ฐํ˜•" ๋˜๋Š” "์›" ํ‘œ์‹œ์šฉ ํžˆํŠธ๋งต ๋ชจ์–‘ ์ง€์›
line_dist_thresh int 15 ๋ผ์ธ ์นด์šดํ„ฐ์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ ์ž„๊ณ„๊ฐ’

์ธ์ˆ˜ model.track

์ด๋ฆ„ ์œ ํ˜• ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
source im0 None ์ด๋ฏธ์ง€ ๋˜๋Š” ๋น„๋””์˜ค์˜ ์†Œ์Šค ๋””๋ ‰ํ† ๋ฆฌ
persist bool False ํ”„๋ ˆ์ž„ ๊ฐ„ ํŠธ๋ž™ ์ง€์†
tracker str botsort.yaml ์ถ”์  ๋ฐฉ๋ฒ• '๋ฐ”์ดํŠธํŠธ๋ž™' ๋˜๋Š” '๋ด‡์†ŒํŠธ'
conf float 0.3 ์‹ ๋ขฐ๋„ ์ž„๊ณ„๊ฐ’
iou float 0.5 IOU ์ž„๊ณ„๊ฐ’
classes list None ํด๋ž˜์Šค๋ณ„๋กœ ๊ฒฐ๊ณผ๋ฅผ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: classes=0 ๋˜๋Š” classes=[0,2,3]).

ํžˆํŠธ๋งต ์ปฌ๋Ÿฌ๋งต

์ปฌ๋Ÿฌ๋งต ์ด๋ฆ„ ์„ค๋ช…
cv::COLORMAP_AUTUMN ๊ฐ€์„ ์ƒ‰์ƒ ์ง€๋„
cv::COLORMAP_BONE ๋ผˆ๋Œ€ ์ƒ‰์ƒ ๋งต
cv::COLORMAP_JET ์ œํŠธ ์ปฌ๋Ÿฌ ์ง€๋„
cv::COLORMAP_WINTER ๊ฒจ์šธ ์ƒ‰์ƒ ์ง€๋„
cv::COLORMAP_RAINBOW ๋ ˆ์ธ๋ณด์šฐ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_OCEAN ๋ฐ”๋‹ค ์ƒ‰์ƒ ์ง€๋„
cv::COLORMAP_SUMMER ์—ฌ๋ฆ„ ์ƒ‰์ƒ ์ง€๋„
cv::COLORMAP_SPRING ๋ด„ ์ƒ‰์ƒ ์ง€๋„
cv::COLORMAP_COOL ๋ฉ‹์ง„ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_HSV HSV(์ƒ‰์กฐ, ์ฑ„๋„, ๊ฐ’) ์ƒ‰์ƒ ๋งต
cv::COLORMAP_PINK ํ•‘ํฌ์ƒ‰ ์ง€๋„
cv::COLORMAP_HOT ํ•ซ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_PARULA ํŒŒ๋ฃฐ๋ผ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_MAGMA ๋งˆ๊ทธ๋งˆ ์ƒ‰์ƒ ์ง€๋„
cv::COLORMAP_INFERNO ์ธํŽ˜๋ฅด๋…ธ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_PLASMA ํ”Œ๋ผ์ฆˆ๋งˆ ์ƒ‰์ƒ ๋งต
cv::COLORMAP_VIRIDIS ๋น„๋ฆฌ๋””์Šค ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_CIVIDIS ์‹œ๋น„๋””์Šค ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_TWILIGHT ํ™ฉํ˜ผ์˜ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_TWILIGHT_SHIFTED ์‹œํ”„ํŠธ๋œ ํ™ฉํ˜ผ ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_TURBO ํ„ฐ๋ณด ์ปฌ๋Ÿฌ ๋งต
cv::COLORMAP_DEEPGREEN ๋”ฅ ๊ทธ๋ฆฐ ์ปฌ๋Ÿฌ ๋งต

์ด๋Ÿฌํ•œ ์ปฌ๋Ÿฌ๋งต์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์–‘ํ•œ ์ƒ‰์ƒ ํ‘œํ˜„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.



์ƒ์„ฑ๋จ 2023-12-07, ์—…๋ฐ์ดํŠธ๋จ 2024-02-03
์ž‘์„ฑ์ž: glenn-jocher (7), AyushExel (1), chr043416@gmail.com (6), 1579093407@qq.com (1)

๋Œ“๊ธ€