log 출력, 관리 관련 함수
def printf(text: str) -> None:
"""
문자열을 강조된 형식으로 출력.
Args:
text (str): 출력할 메시지.
Returns:
None
"""
def error_print(text: str) -> dict[str, Union[int, bool, str]]:
"""
오류 메시지를 강조된 형식으로 출력, 이를 JSON 형식의 딕셔너리로 반환.
Args:
text (str): 오류 메시지.
Returns:
dict[str, Union[int, bool, str]]: 오류 메시지가 포함된 JSON 형식의 딕셔너리.
"""
type convert 관련 함수
def convert_int64(value: Union[int, np.int64]) -> int:
"""
numpy int64 값을 일반 파이썬 int로 변환합니다.
Args:
value (Union[int, np.int64]): 변환할 값.
Returns:
int: 변환된 정수 값.
Raises:
TypeError: 값이 numpy int64 타입이 아닐 경우 예외를 발생.
"""
indexing 관련 함수
def get_index_list(joint_name: str) -> int:
"""
주어진 관절 이름에 대한 리스트 인덱스를 반환.
Args:
joint_name (str): 관절 이름.
Returns:
int: 리스트 관절 인덱스.
"""
def get_index_mp(joint_name: str) -> int:
"""
주어진 관절 이름에 대한 mediapipe 인덱스를 반환.
Args:
joint_name (str): 관절 이름.
Returns:
int: mediapipe 관절 인덱스.
"""
def get_index_eight(step_name: str) -> int:
"""
주어진 골프 스윙 8단계 이름에 대한 인덱스를 반환.
Args:
step_name (str): 골프 스윙 8단계 이름.
Returns:
int: 골프 스윙 8단계 인덱스.
"""
기본적인 각도, 방정식 관련 함수
def center_2d(one_point: list[float], another_point: list[float]) -> list[float]:
"""
두 2D 점의 중점을 계산하여 반환.
Args:
one_point (list[float]): 첫 번째 점의 좌표.
another_point (list[float]): 두 번째 점의 좌표.
Returns:
list[float]: 두 점의 중점 좌표.
"""
def line_2d(one_point: list[float], another_point: list[float]) -> list[float]:
"""
두 점을 받아서 직선의 방정식을 생성하고, 기울기와 절편을 반환.
Args:
one_point (list[float]): 첫 번째 점의 좌표.
another_point (list[float]): 두 번째 점의 좌표.
Returns:
list[float]: [기울기, 절편]을 포함하는 리스트.
"""
def xaxis_angle_2d(point: list[float]) -> float:
"""
주어진 2D 점과 x축 사이의 각도를 계산하여 반환합니다.
Args:
point (list[float]): 2D 점의 좌표.
Returns:
float: x축과의 각도 (도 단위).
"""
기능 관련 함수
def get_tempo(step_frame: dict[str, int]) -> tuple[dict[str, float], dict[str, float]]:
"""
각 구간별 템포와 백스윙/다운스윙 템포를 계산하여 반환.
Args:
step_frame (dict[str, int]): 골프 스윙의 각 단계별 프레임 번호를 담은 딕셔너리.
Returns:
tuple[dict[str, float], dict[str, float]]:
- 구간별 템포를 담은 딕셔너리.
- 백스윙과 다운스윙 템포를 담은 딕셔너리.
"""
def top_position(PoseLandmark: list[list[list[float]]], step_frame: dict[str, int]) -> tuple[str, int]:
"""
탑 스윙에서의 포지션을 평가하고, 오버스윙 여부를 판단하여 결과를 반환.
Args:
PoseLandmark (list[list[list[float]]]): 각 관절의 좌표 정보를 담고 있는 리스트.
step_frame (dict[str, int]): 골프 스윙의 각 단계별 프레임 번호를 담은 딕셔너리.
Returns:
tuple[str, int]:
- 포지션 평가 결과 ("good", "low", "sway", "over swing" 등).
- 오버스윙 후의 프레임 번호.
"""
def get_tempo(step_frame: dict[str, int]) -> tuple[dict[str, float], dict[str, float]]:
"""
각 구간별 템포와 백스윙/다운스윙 템포를 계산하여 반환.
Args:
step_frame (dict[str, int]): 골프 스윙의 각 단계별 프레임 번호를 담은 딕셔너리.
Returns:
tuple[dict[str, float], dict[str, float]]:
- 구간별 템포를 담은 딕셔너리.
- 백스윙과 다운스윙 템포를 담은 딕셔너리.
"""
def plane_angle(joint_name: str, PoseLandmark: list[list[list[float]]], step_frame: dict[str, int], video_length: int) \
-> tuple[list[float], list[float], Optional[float]]:
"""
평면상의 회전 각도를 계산.
Args:
joint_name (str): 분석할 관절의 이름.
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
step_frame (dict[str, int]): 골프 스윙의 각 단계별 프레임 번호를 담은 딕셔너리.
video_length (int): 전체 비디오의 길이 (프레임 수).
Returns:
tuple[list[float], list[float], Optional[float]]:
- xy 평면에서의 회전 각도 리스트.
- xz 평면에서의 회전 각도 리스트.
- (무릎인 경우) address부터 top까지의 최대 무릎 각도.
"""
def path_angle(joint_name: str, step_frame: dict[str, int], PoseLandmark: list[list[list[float]]], finish_idx: int, club: int) -> dict[str, float]:
"""
골프 스윙 경로에서 각도를 계산하고, 면적을 구함.
Args:
joint_name (str): 분석할 관절의 이름.
step_frame (dict[str, int]): 골프 스윙의 각 단계별 프레임 번호를 담은 딕셔너리.
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
finish_idx (int): 최종 finish 단계의 프레임 번호.
club (int): 클럽의 길이 또는 표준화에 사용되는 값.
Returns:
dict[str, float]: 경로의 각도와 면적을 포함하는 딕셔너리.
"""
def max_base_address(address_x: float, address_y: float, path_x: list[float], path_y: list[float], width: int, height: int) -> list[str, str]:
"""
어드레스와의 최대 거리를 계산하고 방향을 반환.
Args:
address_x (float): 어드레스의 x 좌표.
address_y (float): 어드레스의 y 좌표.
path_x (list[float]): 경로의 x 좌표 리스트.
path_y (list[float]): 경로의 y 좌표 리스트.
width (int): 비디오의 폭 (픽셀).
height (int): 비디오의 높이 (픽셀).
Returns:
list[str, str]: x 및 y 방향으로 최대 거리를 나타내는 문자열 리스트.
"""
def get_movements(joint_name: str, step_frame: dict[str, int], cvPoseLandmark: list[list[list[float]]],
width: int, height: int, video_length: int) -> tuple[dict[str, float], list[str], list[str]]:
"""
특정 관절의 움직임 크기를 계산.
Args:
joint_name (str): 분석할 관절의 이름.
step_frame (dict[str, int]): 골프 스윙의 각 단계별 프레임 번호를 담은 딕셔너리.
cvPoseLandmark (list[list[list[float]]]): 각 프레임에서의 포즈 랜드마크 좌표를 담고 있는 리스트.
width (int): 비디오의 폭 (픽셀).
height (int): 비디오의 높이 (픽셀).
video_length (int): 전체 비디오의 길이 (프레임 수).
Returns:
tuple[dict[str, float], list[str], list[str]]:
- 각 스텝에서의 움직임 크기를 포함하는 딕셔너리.
- x 축에서의 프레임별 위치 변화 리스트.
- y 축에서의 프레임별 위치 변화 리스트.
"""
def get_step(video_length: int, PoseLandmark: list[list[list[float]]]) -> list[int]:
"""
골프 스윙의 8단계 프레임을 판별.
Args:
video_length (int): 전체 비디오의 길이 (프레임 수).
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
Returns:
list[int]: 골프 스윙의 8단계에 해당하는 프레임 번호 리스트.
"""
def finish_top(PoseLandmark: list[list[list[float]]], step_frame: list[int], video_length: int) -> int:
"""
골프 스윙의 피니시 단계 가장 높은 프레임을 판별.
Args:
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
step_frame (list[int]): 각 단계의 프레임 번호 리스트.
video_length (int): 전체 비디오의 길이 (프레임 수).
Returns:
int: 피니시 단계의 최종 프레임 번호.
"""
데이터 전처리 관련 함수
def impact_wrist(PoseLandmark: list[list[list[float]]], cvPoseLandmark: list[list[list[float]]],
step_frame: list[int], width: int, height: int, over_top: int) -> None:
"""
임팩트 시 손목 위치를 추정하여 스무딩.
Args:
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
cvPoseLandmark (list[list[list[float]]]): 영상의 각 프레임에 대한 포즈 랜드마크 좌표를 담고 있는 리스트.
step_frame (list[int]): 골프 스윙의 각 단계별 프레임 번호를 담은 리스트.
width (int): 비디오의 폭 (픽셀).
height (int): 비디오의 높이 (픽셀).
over_top (int): 오버스윙 후의 프레임 번호.
Returns:
None
"""
def conv_smoothing(video_length: int, PoseLandmark: list[list[list[float]]], cvPoseLandmark: list[list[list[float]]],
width: int, height: int, empty_frame: list[int]) -> None:
"""
비디오의 포즈 랜드마크 좌표에 대해 컨볼루션 스무딩을 적용.
Args:
video_length (int): 전체 비디오의 길이 (프레임 수).
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
cvPoseLandmark (list[list[list[float]]]): 각 프레임에서의 포즈 랜드마크 좌표를 담고 있는 리스트.
width (int): 비디오의 폭 (픽셀).
height (int): 비디오의 높이 (픽셀).
empty_frame (list[int]): 포즈 랜드마크를 감지하지 못한 프레임 번호 리스트.
Returns:
None
"""
def wrist_smoothing(step_frame: list[int], PoseLandmark: list[list[list[float]]], cvPoseLandmark: list[list[list[float]]],
width: int, height: int) -> None:
"""
손목 좌표에 스무딩을 적용.
Args:
step_frame (list[int]): 각 단계의 프레임 번호 리스트.
PoseLandmark (list[list[list[float]]]): 각 관절의 포즈 랜드마크 좌표를 담고 있는 리스트.
cvPoseLandmark (list[list[list[float]]]): 각 프레임에서의 포즈 랜드마크 좌표를 담고 있는 리스트.
width (int): 비디오의 폭 (픽셀).
height (int): 비디오의 높이 (픽셀).
Returns:
None
"""
영상 자체 변환 관련 함수
def find_crop_area(start_point: list[float], end_point: list[float], ratio: list[int]) -> tuple[list[int], list[int]]:
"""
지정된 비율을 유지하면서 최적의 크롭 영역 찾기.
Args:
start_point (list[float]): 크롭 영역의 시작점 좌표.
end_point (list[float]): 크롭 영역의 끝점 좌표.
ratio (list[int]): 원하는 크롭 비율 (너비:높이).
Returns:
tuple[list[int], list[int]]: 크롭 영역의 시작점과 끝점을 나타내는 좌표 리스트.
"""
def adaptive_frame_cutting(video_name: str, target_frame: int) -> None:
"""
프레임 수를 줄이기 위해 비디오를 지정된 프레임 수로 자르기.
Args:
video_name (str): 자를 비디오 파일의 이름.
target_frame (int): 목표 프레임 수.
Returns:
None
"""
model관련 함수
def process_video_with_model(video_name: str, hand_type: str, complexity: int) -> tuple:
"""
지정된 Complexity에 따른 MediaPipe 포즈 모델을 사용하여 비디오를 처리
Args:
video_name (str): 처리할 비디오 파일의 경로
hand_type (str): 처리할 손의 유형 ('left' 또는 'right')
complexity (int): MediaPipe 포즈 모델의 복잡도 수준 (1 또는 2)
Returns:
tuple: 다음을 포함하는 튜플.
- list: 비디오의 모든 프레임에서 각 관절에 대한 포즈 랜드마크 좌표를 포함하는 리스트
- list[int]: 포즈 랜드마크를 감지하지 못한 프레임 번호들의 리스트
- int: 총 처리된 프레임 수
"""