AI딥러닝

딥러닝 모델을 재사용하되 스프링부트에서 스트리밍할것

Ystory96 2026. 2. 12. 21:23

★ 목표 : AI모델 재사용하기

스프링부트 위주로 설명하겠습니다.

 

1. Top

차량탐지에서는 원래 학습한 모델을 가지고 실습을 했습니다.

선생님의 차량탐지에서는 '차량탐지'에서 실습한 모델을 재사용 했습니다.

<li><a href="car">차량탐지 </a></li>
<li><a href="teacher">선생님의 차량탐지 </a></li>

 

2. Controller

제일 중요한 부분입니다

Top에서 Controller로 넘어왔으면, 여기서 파이썬 코드를 실행해줘야 합니다

저는 차 인식을 딥러닝으로 학습시킨 파이썬 파일 위치가 아래와 같습니다>>

"C:/sundo/springboot/day10_image/src/main/resources/static/python/human.py"

그리고 자바와 호환이 되어 동영상이 실행될 수 있도록 아래 코드가 필요합니다.(상황마다 다르니 생성형 AI의 도움을 받으세요)>>

processBuilder.redirectErrorStream(true);

파일을 읽어옵시다>>

BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

전체코드입니다>>

@GetMapping("/car")
public String ss8() throws IOException, InterruptedException {
    ProcessBuilder processBuilder = new ProcessBuilder("python",
                    "C:/sundo/springboot/day10_image/src/main/resources/static/python/car.py");
    processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
    processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
    processBuilder.redirectErrorStream(true);
    Process process = processBuilder.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line); // or logger.info(line);}
        int exitCode = process.waitFor();
    }
    return "redirect:/carview";
}
 

3. PY

먼저 동영상 재생할 수 있는 cv2와 ultralytics 설치 꼭 해주세요>>

import cv2
from ultralytics import YOLO

import os

 

그리고 다음으로 모델의 경로를 입력해주고

학습시킬 원본 동영상 경로도 입력해줍니다>>

project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))
model_path = r"C:\MBCAI_car\datasets\runs\detect\debris_yolo8\weights\best.pt"
video_path = r"C:\sundo\springboot\day10_image\src\main\resources\static\video\car.mp4"

 

그리고 학습시킨 모델을 저장할 저장 경로도 입력해줍니다

output_path는 새로 학습된 동영상이고

input_path는 인지할 사물의 개수를 세어주는 동영상입니다>>

input_path = r"C:\sundo\springboot\day10_image\src\main\resources\static\video\car_output_count.mp4"
output_path = r"C:\sundo\springboot\day10_image\src\main\resources\static\video\carout.mp4"
model = YOLO(model_path)
cap = cv2.VideoCapture(video_path)

 

# 프레임 사이즈 정보
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)

# 비디오 저장 객체 설정 (코덱: mp4v)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(input_path, fourcc, fps, (width, height))

 

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 객체 추적
    results = model.track(source=frame, persist=True, conf=0.1, show=False, verbose=False)
    # 프레임 복사해서 그리기용
    annotated_frame = frame.copy()

    if results and results[0].boxes.id is not None:
        boxes = results[0].boxes

        for box in boxes:
            # ID 및 클래스
            track_id = int(box.id[0])
            cls_id = int(box.cls[0])
            x1, y1, x2, y2 = map(int, box.xyxy[0])

            # 원하는 라벨 형식: #1, #2, ...
            label_text = f"car {track_id}"

            # 박스 그리기
            cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), (255, 0, 0), 2)

            # 라벨 텍스트 배경
            ((text_width, text_height), _) = cv2.getTextSize(label_text, cv2.FONT_HERSHEY_SIMPLEX, 0.8, 2)
            cv2.rectangle(annotated_frame, (x1, y1 - text_height - 10), (x1 + text_width, y1), (255, 0, 0), -1)

            # 라벨 텍스트
            cv2.putText(annotated_frame, label_text, (x1, y1 - 5),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2)

    # 프레임 출력
    #cv2.imshow("test", annotated_frame)

    #if cv2.waitKey(1) & 0xFF == ord("q"):
    #    break
    out.write(annotated_frame)

 

cap.release()
out.release()
cv2.destroyAllWindows()

 

****여기서 너무 중요한 작업이 있습니다. 바로 FFmpeg를 다운로드 받아야 합니다.

요것이 있어야 동영상을 재생할 수 있습니다. 반드시 전체 버전으로 다운로드 받으셔야 합니다.

ffmpeg/bin/ ffmpeg.exe 파일이 있어야 하기 때문입니다>>

https://www.ffmpeg.org/

 

FFmpeg

Converting video and audio has never been so easy. $ ffmpeg -i input.mp4 output.avi     News August 22nd, 2025, FFmpeg 8.0 "Huffman" A new major release, FFmpeg 8.0 "Huffman", is now available for download. Thanks to several delays, and modernization of

www.ffmpeg.org

 

import subprocess

# ffmpeg 명령어 구성
command = [
    r"C:\ffmpeg\bin\ffmpeg.exe",
    "-y",
    "-i", input_path,
    "-c:v", "libx264",
    "-preset", "fast",
    "-crf", "23",
    "-c:a", "aac",
    "-movflags", "+faststart",
    output_path
]

# ffmpeg 실행
try:
    subprocess.run(command, check=True)
    print("Video converted successfully!")
except subprocess.CalledProcessError as e:
    print("Error during conversion:", {e})

 

 

****carout.mp4와 car_output_count.mp4 가 만들어졌습니다.

 

 

4. Controller로 돌아오기 return carVeiw.html

return "redirect:/carview";
}

@GetMapping("/carview")
public String ss8_2(Model model) throws IOException {
model.addAttribute("text","차량 탐지 결과");
    model.addAttribute("data", "/video/"); // 폴더 경로 추가 (HTML의 ${data}에 대응)
model.addAttribute("video","carout.mp4");
return "carView";
}

 

 

5. carView.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div th:replace="~{top::menu}"></div>
<body>
<div class="container">
    <h2 th:text="${text}"></h2>
    <video width="720" controls>
        <source th:src="${data}+${video}" type="video/mp4">
        브라우저가 video 태그를 지원하지 않습니다.
    </video>
</div>
</body>
</html>

 

 

6. 실행

 

 

6. 다음 모델을 가지고 다른 영상에도 적용해보겠습니다

 

.

** 모델 코딩하실때 가장 중요한 포인트는 경로입니다. 그래서 다음 아래에 꼭 체크해야 하는 경로를 정리해두겠습니다.

 

1. 파이썬 인터프리터 경로 (python.exe / python3)

스프링부트의 ProcessBuilder가 파이썬 코드를 실행하기 위해 가장 먼저 찾는 경로입니다.

 

2. 파이썬 스크립트 파일 경로 (.py)

실제 AI 모델 로드 및 영상 처리 로직이 담긴 파이썬 파일의 위치입니다.

 

3. 입력 영상 원본 경로 (Input Video Path)

파이썬 모델이 분석해야 할 원본 영상 파일 주소입니다.

 

4. 출력 영상/데이터 전송 경로 (Output/Stream Path)

파이썬이 분석한 결과(바운딩 박스가 그려진 영상 등)를 스프링부트로 다시 보낼 때 사용하는 통로입니다.

 

5. FFmpeg 실행 파일 경로 (ffmpeg.exe)

시스템 어디서나 FFmpeg 명령어를 인식할 수 있도록 실행 파일의 위치를 관리해야 합니다.

 

끝.