Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- difftime
- 히스토그램 그리기
- %in%
- count
- 불순도제거
- 총과 카드만들기
- 그래프시각화
- sql
- Intersect
- Sum
- 빅데이터분석
- if문 작성법
- 상관관계
- 막대그래프
- merge
- 순위출력
- 그래프 생성 문법
- 팀스파르타
- loop 문
- 데이터분석가
- 빅데이터
- max
- 회귀분석 알고리즘
- 정보획득량
- Dense_Rank
- 여러 데이터 검색
- 회귀분석
- 데이터분석
- 단순회귀 분석
- sqld
Archives
- Today
- Total
ch0nny_log
[빅데이터분석] 딥러닝_21. 영상 인터페이스 구현 (+streamlit 생성) 본문
빅데이터 분석(with 아이티윌)/deep learning
[빅데이터분석] 딥러닝_21. 영상 인터페이스 구현 (+streamlit 생성)
chonny 2024. 10. 31. 11:06
예제1. streamlit 에서 영상 업로드후 play 시키기
1. 깃허브에 app16.py 로 아래 코드 업로드
import streamlit as st
# 제목 설정
st.title("Video Player App")
# 파일 업로드
uploaded_file = st.file_uploader("Upload a video file", type=["mp4", "mov", "avi"])
# 파일이 업로드되었는지 확인
if uploaded_file is not None:
# 비디오 플레이어
st.video(uploaded_file)
else:
st.write("Please upload a video file to play.")
2. streamlit 으로 app16 create app 만들기
Streamlit • A faster way to build and share data apps
3. 다운로드 받은 파일 browse files 에 업로드
예제2. 원본 영상 옆에 결과 영상 나오게하기
1. app16.py 파일에 있는 코드 모두 지우고 아래 코드로 채우기
import streamlit as st
# 전체 레이아웃을 넓게 설정
st.set_page_config(layout="wide")
# 제목 설정
st.title("비디오 사물 검출 앱")
# 전체 레이아웃을 컨테이너로 감싸기
with st.container():
col1, col2 = st.columns(2) # 열을 균등하게 분배하여 넓게 표시
# 파일 업로드
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
with col1:
st.header("원본 영상")
if uploaded_file is not None:
st.video(uploaded_file)
else:
st.write("원본 영상을 표시하려면 비디오 파일을 업로드하세요.")
with col2:
st.header("사물 검출 결과 영상")
if "processed_video" in st.session_state:
st.video(st.session_state["processed_video"])
else:
st.write("여기에 사물 검출 결과가 표시됩니다.")
# 사물 검출 버튼 추가
if st.button("사물 검출 실행"):
if uploaded_file is not None:
st.session_state["processed_video"] = uploaded_file
st.success("사물 검출이 완료되어 오른쪽에 표시됩니다.")
else:
st.warning("사물 검출을 실행하려면 비디오 파일을 업로드하세요.")
2. streamlit 재구현
예제3. 파일 업로드하는 버튼을 위로 올리기
- 위와 동일하게 아래 코드로 수정
import streamlit as st
# 전체 레이아웃을 넓게 설정
st.set_page_config(layout="wide")
# 제목 설정
st.title("프로젝트 제목 사물 검출 앱")
# 파일 업로드
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
# 전체 레이아웃을 컨테이너로 감싸기
with st.container(): # with 절로 하나의 기능을 하는 코드를 묶어줌 (가독성 높이기)
col1, col2 = st.columns(2) # 열을 균등하게 분배하여 넓게 표시
# 파일 업로드
# uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
with col1:
st.header("원본 영상") # col1 영역의 제목
if uploaded_file is not None: # 영상이 업로드가 되었다면
st.video(uploaded_file) # 영상 플레이해라 !
else:
st.write("원본 영상을 표시하려면 비디오 파일을 업로드하세요.")
with col2:
st.header("사물 검출 결과 영상") # col2 에 해당하는 영역의 제목
if "processed_video" in st.session_state: # 사물검출 완료된 비디오가 있으면
st.video(st.session_state["processed_video"]) # 그 비디오를 플레이해라
else:
st.write("여기에 사물 검출 결과가 표시됩니다.")
# 사물 검출 버튼 추가
if st.button("사물 검출 실행"): # 사물검출 실행이라는 버튼을 누르면
if uploaded_file is not None: # 업로드된 영상이 있다면
st.session_state["processed_video"] = uploaded_file # 검출된 영상을 사용
st.success("사물 검출이 완료되어 오른쪽에 표시됩니다.") # 이 메세지 출력
else:
st.warning("사물 검출을 실행하려면 비디오 파일을 업로드하세요.")
예제4. 원본영상 옆에 빈화면 표시
- 위와 동일하게 아래 코드로 수정
import streamlit as st
# 전체 레이아웃을 넓게 설정
st.set_page_config(layout="wide")
# 제목 설정
st.title("프로젝트 제목 사물 검출 앱")
# 파일 업로드
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
# 전체 레이아웃을 컨테이너로 감싸기
with st.container(): # with 절로 하나의 기능을 하는 코드를 묶어줌 (가독성 높이기)
col1, col2 = st.columns(2) # 열을 균등하게 분배하여 넓게 표시
# 파일 업로드
# uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
with col1:
st.header("원본 영상") # col1 영역의 제목
if uploaded_file is not None: # 영상이 업로드가 되었다면
st.video(uploaded_file) # 영상 플레이해라 !
else:
st.write("원본 영상을 표시하려면 비디오 파일을 업로드하세요.")
with col2:
st.header("사물 검출 결과 영상") # col2 에 해당하는 영역의 제목
result_placeholder = st.empty()
if "processed_video" in st.session_state: # 사물검출 완료된 비디오가 있으면
st.video(st.session_state["processed_video"]) # 그 비디오를 플레이해라
else:
#st.write("여기에 사물 검출 결과가 표시됩니다.")
result_placeholder.markdown(
"""
<div style='width:100%; height:620px; background-color:#d3d3d3; display:flex; align-items:center; justify-content:center; border-radius:5px;'>
<p style='color:#888;'>여기에 사물 검출 결과가 표시됩니다.</p>
</div>
""",
unsafe_allow_html=True,
)
# 사물 검출 버튼 추가
if st.button("사물 검출 실행"): # 사물검출 실행이라는 버튼을 누르면
if uploaded_file is not None: # 업로드된 영상이 있다면
st.session_state["processed_video"] = uploaded_file # 검출된 영상을 사용
st.success("사물 검출이 완료되어 오른쪽에 표시됩니다.") # 이 메세지 출력
else:
st.warning("사물 검출을 실행하려면 비디오 파일을 업로드하세요.")
예제5. 사물검출 버튼 색깔 변경하기(오류 이슈로 일반 패스_바로 예제6으)
import streamlit as st
# 전체 레이아웃을 넓게 설정
st.set_page_config(layout="wide")
# 제목 설정
st.title("비디오 사물 검출 앱")
# 파일 업로드 버튼을 상단으로 이동
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
# 전체 레이아웃을 컨테이너로 감싸기
with st.container():
col1, col2 = st.columns(2) # 열을 균등하게 분배하여 넓게 표시
with col1:
st.header("원본 영상")
if uploaded_file is not None:
st.video(uploaded_file)
else:
st.write("원본 영상을 표시하려면 비디오 파일을 업로드하세요.")
with col2:
st.header("사물 검출 결과 영상")
# 사물 검출 결과가 나타날 자리 확보 및 고정 높이 회색 박스 스타일 추가
result_placeholder = st.empty()
if "processed_video" in st.session_state and st.session_state["processed_video"] is not None:
result_placeholder.video(st.session_state["processed_video"])
else:
result_placeholder.markdown(
"""
<div style='width:100%; height:620px; background-color:#d3d3d3; display:flex; align-items:center; justify-content:center; border-radius:5px;'>
<p style='color:#888;'>여기에 사물 검출 결과가 표시됩니다.</p>
</div>
""",
unsafe_allow_html=True,
)
# 버튼 스타일 설정
st.markdown(
"""
<style>
.stButton > button {
background-color: #4d4d4d; /* 진한 회색 */
color: #ffffff; /* 흰색 텍스트 */
font-weight: bold; /* 굵은 글씨 */
padding: 12px 24px;
font-size: 16px;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s;
}
.stButton > button:hover {
background-color: #333333; /* 호버 시 더 진한 회색 */
}
</style>
""",
unsafe_allow_html=True
)
# 사물 검출 버튼 추가 및 클릭 이벤트 처리
if st.button("사물 검출 실행"):
if uploaded_file is not None:
# 여기에 사물 검출을 수행하는 코드를 추가하고, 결과를 st.session_state["processed_video"]에 저장
st.session_state["processed_video"] = None # 실제 결과 영상으로 바꿔야 함
result_placeholder.markdown(
"<div style='width:100%; height:620px; background-color:#d3d3d3; display:flex; align-items:center; justify-content:center; border-radius:5px;'>"
"<p style='color:#888;'>사물 검출 결과 영상이 여기에 표시됩니다.</p>"
"</div>",
unsafe_allow_html=True,
)
st.success("사물 검출이 완료되어 오른쪽에 표시됩니다.")
else:
st.warning("사물 검출을 실행하려면 비디오 파일을 업로드하세요.")
예제6. 모델 불러와서 사물 검출 구현하기
1. 깃허브 '수익화를 위한 requirements.txt 수정'
sentence_transformers
pandas
streamlit
opencv-python-headless
ultralytics
ffmpeg-python
ffmpeg
moviepy
2. app16.py 코드 수정
import streamlit as st
from ultralytics import YOLO
import tempfile
import cv2
import os
# 전체 레이아웃을 넓게 설정
st.set_page_config(layout="wide")
# 제목 설정
st.title("프로젝트 제목 사물 검출 앱")
# 모델 파일 업로드
model_file = st.file_uploader("모델 파일을 업로드하세요", type=["pt"])
if model_file:
with tempfile.NamedTemporaryFile(delete=False, suffix=".pt") as temp_model_file:
temp_model_file.write(model_file.read())
model_path = temp_model_file.name
model = YOLO(model_path)
st.success("모델이 성공적으로 로드되었습니다.")
# 비디오 파일 업로드
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
# 전체 레이아웃을 컨테이너로 감싸기
with st.container(): # 코드 가독성을 높이기 위해 컨테이너로 묶음
col1, col2 = st.columns(2) # 열을 균등하게 분배하여 넓게 표시
# 원본 영상 표시
with col1:
st.header("원본 영상") # col1 영역의 제목
if uploaded_file is not None: # 영상이 업로드되었는지 확인
st.video(uploaded_file) # 원본 영상 표시
else:
st.write("원본 영상을 표시하려면 비디오 파일을 업로드하세요.")
# 사물 검출 결과 영상 표시
with col2:
st.header("사물 검출 결과 영상") # col2 영역의 제목
result_placeholder = st.empty() # 빈 영역 확보
if "processed_video" in st.session_state: # 사물 검출 결과가 있으면
result_placeholder.video(st.session_state["processed_video"]) # 결과 영상 표시
else:
# 검출 결과가 없을 때 회색 박스 표시
result_placeholder.markdown(
"""
<div style='width:100%; height:620px; background-color:#d3d3d3; display:flex; align-items:center; justify-content:center; border-radius:5px;'>
<p style='color:#888;'>여기에 사물 검출 결과가 표시됩니다.</p>
</div>
""",
unsafe_allow_html=True,
)
# 사물 검출 실행 버튼 추가
if st.button("사물 검출 실행"):
if uploaded_file is None:
st.warning("사물 검출을 실행하려면 비디오 파일을 업로드하세요.")
elif model_file is None:
st.warning("사물 검출을 실행하려면 모델 파일을 업로드하세요.")
else:
# 임시 파일 경로 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_output:
output_path = temp_output.name
with tempfile.NamedTemporaryFile(delete=False) as temp_input:
temp_input.write(uploaded_file.read())
temp_input_path = temp_input.name
# 원본 비디오를 읽기
cap = cv2.VideoCapture(temp_input_path)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
# 프레임 단위로 사물 검출 수행
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# YOLO 모델로 예측 수행
results = model(frame)
detections = results[0].boxes if len(results) > 0 else []
if len(detections) > 0:
for box in detections:
x1, y1, x2, y2 = map(int, box.xyxy[0])
confidence = box.conf[0]
class_id = int(box.cls[0])
class_name = model.names[class_id]
label = f"{class_name} {confidence:.2f}"
# 검출된 객체의 바운딩 박스 및 라벨 표시
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
else:
# 검출 결과가 없을 때 로그 출력
st.write(f"Frame {frame_count}: No detections")
out.write(frame)
frame_count += 1
# 비디오 객체 해제
cap.release()
out.release()
# 결과 비디오를 세션 상태에 저장하여 표시
st.session_state["processed_video"] = output_path
result_placeholder.video(output_path)
st.success("사물 검출이 완료되어 오른쪽에 표시됩니다.")
예제 7. 디텍션 결과 디버깅하기
- 본 코드에 아래 코드 추가
import streamlit as st
from ultralytics import YOLO
import tempfile
import cv2
import os
# 전체 레이아웃을 넓게 설정
st.set_page_config(layout="wide")
# 제목 설정
st.title("비디오 사물 검출 앱")
# 모델 파일 업로드
model_file = st.file_uploader("모델 파일을 업로드하세요", type=["pt"])
if model_file:
with tempfile.NamedTemporaryFile(delete=False, suffix=".pt") as temp_model_file:
temp_model_file.write(model_file.read())
model_path = temp_model_file.name
model = YOLO(model_path)
st.success("모델이 성공적으로 로드되었습니다.")
# 비디오 파일 업로드
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
# 전체 레이아웃을 컨테이너로 감싸기
with st.container():
col1, col2 = st.columns(2)
with col1:
st.header("원본 영상")
if uploaded_file is not None:
st.video(uploaded_file)
else:
st.write("원본 영상을 표시하려면 비디오 파일을 업로드하세요.")
with col2:
st.header("사물 검출 결과 영상")
result_placeholder = st.empty()
if "processed_video" in st.session_state and st.session_state["processed_video"] is not None:
result_placeholder.video(st.session_state["processed_video"])
else:
result_placeholder.markdown(
"""
<div style='width:100%; height:620px; background-color:#d3d3d3; display:flex; align-items:center; justify-content:center; border-radius:5px;'>
<p style='color:#888;'>여기에 사물 검출 결과가 표시됩니다.</p>
</div>
""",
unsafe_allow_html=True,
)
# 버튼 스타일 설정
st.markdown(
"""
<style>
.stButton > button {
background-color: #4d4d4d;
color: #ffffff;
font-weight: bold;
padding: 12px 24px;
font-size: 16px;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s;
}
.stButton > button:hover {
background-color: #333333;
}
</style>
""",
unsafe_allow_html=True
)
# 사물 검출 버튼 클릭 이벤트 처리
if st.button("사물 검출 실행") and uploaded_file and model_file:
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_output:
output_path = temp_output.name
with tempfile.NamedTemporaryFile(delete=False) as temp_input:
temp_input.write(uploaded_file.read())
temp_input_path = temp_input.name
cap = cv2.VideoCapture(temp_input_path)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# YOLO 모델로 예측 수행 및 디버깅
results = model(frame)
detections = results[0].boxes if len(results) > 0 else []
if len(detections) > 0:
for box in detections:
x1, y1, x2, y2 = map(int, box.xyxy[0])
confidence = box.conf[0]
class_id = int(box.cls[0])
class_name = model.names[class_id]
label = f"{class_name} {confidence:.2f}"
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
st.write(f"Frame {frame_count}: {len(detections)} detections")
else:
# 검출 결과가 없을 때도 원본 프레임을 저장
st.write(f"Frame {frame_count}: No detections - Original frame saved")
# 원본 또는 검출된 프레임을 그대로 저장
out.write(frame)
frame_count += 1
cap.release()
out.release()
# 결과 비디오를 st.session_state에 저장하여 스트림릿에 표시
st.session_state["processed_video"] = output_path
result_placeholder.video(output_path)
st.success("사물 검출이 완료되어 오른쪽에 표시됩니다.")
# 다운로드 링크 제공
with open(output_path, "rb") as file:
st.download_button(
label="결과 영상 다운로드",
data=file,
file_name="detected_video.avi",
mime="video/avi"
)
예제8. 결과 다운로드 하기
비디오 사물 검출 및 재인코딩 앱 코드
import streamlit as st
from ultralytics import YOLO
import tempfile
import cv2
from moviepy.editor import VideoFileClip
import os
# 페이지 레이아웃 설정
st.set_page_config(layout="wide")
# 제목
st.title("비디오 사물 검출 및 재인코딩 앱")
# 모델 파일 업로드
model_file = st.file_uploader("모델 파일을 업로드하세요", type=["pt"])
if model_file:
with tempfile.NamedTemporaryFile(delete=False, suffix=".pt") as temp_model_file:
temp_model_file.write(model_file.read())
model_path = temp_model_file.name
model = YOLO(model_path)
st.success("모델이 성공적으로 로드되었습니다.")
# 비디오 파일 업로드
uploaded_file = st.file_uploader("비디오 파일을 업로드하세요", type=["mp4", "mov", "avi"])
# 원본 영상 표시
if uploaded_file is not None:
st.header("원본 영상")
st.video(uploaded_file)
# 사물 검출 실행 버튼
if st.button("사물 검출 실행") and uploaded_file and model_file:
# 임시 파일 경로 생성
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_output:
output_path = temp_output.name
# 원본 비디오 파일을 임시 파일로 저장
with tempfile.NamedTemporaryFile(delete=False) as temp_input:
temp_input.write(uploaded_file.read())
temp_input_path = temp_input.name
# 비디오 처리 시작
cap = cv2.VideoCapture(temp_input_path)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
# 프레임별로 사물 검출 수행
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# YOLO 모델로 예측 수행
results = model(frame)
detections = results[0].boxes if len(results) > 0 else []
# 검출된 객체에 대해 바운딩 박스 그리기
for box in detections:
x1, y1, x2, y2 = map(int, box.xyxy[0])
confidence = box.conf[0]
class_id = int(box.cls[0])
class_name = model.names[class_id]
label = f"{class_name} {confidence:.2f}"
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
out.write(frame)
cap.release()
out.release()
# moviepy를 사용해 재인코딩 수행
st.header("재인코딩된 결과 영상")
reencoded_path = output_path.replace(".mp4", "_reencoded.mp4")
clip = VideoFileClip(output_path)
clip.write_videofile(reencoded_path, codec="libx264", audio_codec="aac")
# 재인코딩된 비디오 다운로드 버튼 제공
with open(reencoded_path, "rb") as file:
st.download_button(
label="재인코딩된 결과 영상 다운로드",
data=file,
file_name="reencoded_video.mp4",
mime="video/mp4"
)
# 결과 영상 재생을 위해 업로드
uploaded_result = st.file_uploader("결과 영상을 업로드하세요", type=["mp4"])
if uploaded_result is not None:
st.header("사물 검출 결과 영상")
st.video(uploaded_result)
'빅데이터 분석(with 아이티윌) > deep learning' 카테고리의 다른 글
[빅데이터분석] 딥러닝_20. 홈페이지에 있는 일반 상담 챗봇 만들기(+streamlit 업로드) (0) | 2024.10.30 |
---|---|
[빅데이터분석] 딥러닝_19. 자연어 처리 신경망 만들어서 챗봇 만들기 (2) | 2024.10.30 |
[빅데이터분석] 딥러닝_17.영상 속에서 사물인식하기 (0) | 2024.10.28 |
[빅데이터분석] 딥러닝_16. 사진 속에서 검출 인터페이스 만들기 (1) | 2024.10.24 |
[빅데이터분석] 딥러닝_15. 딥러닝의 역사 (0) | 2024.10.22 |