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

๊ณ ๊ธ‰ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”: 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 ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•œ ํžˆํŠธ๋งต

import cv2

from ultralytics import YOLO, solutions

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 = solutions.Heatmap(
    colormap=cv2.COLORMAP_PARULA,
    view_img=True,
    shape="circle",
    classes_names=model.names,
)

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()
import cv2

from ultralytics import YOLO, solutions

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 = solutions.Heatmap(
    colormap=cv2.COLORMAP_PARULA,
    view_img=True,
    shape="circle",
    count_reg_pts=line_points,
    classes_names=model.names,
)

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()
import cv2

from ultralytics import YOLO, solutions

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 polygon points
region_points = [(20, 400), (1080, 404), (1080, 360), (20, 360), (20, 400)]

# Init heatmap
heatmap_obj = solutions.Heatmap(
    colormap=cv2.COLORMAP_PARULA,
    view_img=True,
    shape="circle",
    count_reg_pts=region_points,
    classes_names=model.names,
)

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()
import cv2

from ultralytics import YOLO, solutions

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 = solutions.Heatmap(
    colormap=cv2.COLORMAP_PARULA,
    view_img=True,
    shape="circle",
    count_reg_pts=region_points,
    classes_names=model.names,
)

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()
import cv2

from ultralytics import YOLO, solutions

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 = solutions.Heatmap(
    colormap=cv2.COLORMAP_PARULA,
    view_img=True,
    shape="circle",
    classes_names=model.names,
)

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

from ultralytics import YOLO, solutions

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 = solutions.Heatmap(
    colormap=cv2.COLORMAP_PARULA,
    view_img=True,
    shape="circle",
    classes_names=model.names,
)

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()

์ธ์ˆ˜ Heatmap()

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

์ธ์ˆ˜ 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 ๋”ฅ ๊ทธ๋ฆฐ ์ปฌ๋Ÿฌ ๋งต

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



Created 2023-12-07, Updated 2024-06-10
Authors: glenn-jocher (11), IvorZhu331 (1), RizwanMunawar (8), AyushExel (1), 1579093407@qq.com (1)

๋Œ“๊ธ€