Skip to content

Commit

Permalink
Merge branch 'main' into feat/readme
Browse files Browse the repository at this point in the history
  • Loading branch information
taeyang916 authored Mar 30, 2024
2 parents 8cbf432 + f4285e8 commit df4ff90
Show file tree
Hide file tree
Showing 14 changed files with 825 additions and 65 deletions.
138 changes: 138 additions & 0 deletions data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@



# 🔊 Voice2Face-Data



<img src="https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=Python&logoColor=white"> <img src="https://img.shields.io/badge/opencv-5C3EE8?style=for-the-badge&logo=opencv&logoColor=white"> <img src="https://img.shields.io/badge/git-F05032?style=for-the-badge&logo=git&logoColor=white"> <img src="https://img.shields.io/badge/NCP-03C75A?style=for-the-badge&logo=Naver&logoColor=white"> <img src="https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=Linux&logoColor=white"> <img src="https://img.shields.io/badge/Selenium-43B02A?style=for-the-badge&logo=Selenium&logoColor=white"> <img src="https://img.shields.io/badge/Numpy-013243?style=for-the-badge&logo=Numpy&logoColor=white"> <img src="https://img.shields.io/badge/Pytorch-EE4C2C?style=for-the-badge&logo=Pytorch&logoColor=white"> <img src="https://img.shields.io/badge/FFmpeg-007808?style=for-the-badge&logo=FFmpeg&logoColor=white">



## Project Structure

```
data
┣ audio
┃ ┣ audio_check_dB.py
┃ ┣ audio_dB_crop.py
┃ ┗ audio_wav_cropping.py
┣ crawling
┃ ┣ crawling_detect.py
┃ ┣ crawling_rename_video.py
┃ ┣ crawling_select_csv.py
┃ ┣ crawling_urlsave.py
┃ ┗ crawling_videosave.py
┣ image
┃ ┣ image_clipseg2.py
┃ ┗ image_face_frame.py
┣ relabel
┃ ┣ relabel_detect_getframe.py
┃ ┣ relabel_select_csv.py
┃ ┗ relabel_Vox_age.py
┣ total
┃ ┣ total_audio_video_image.py
┃ ┗ total_origin_remove.py
┣ video
┃ ┣ video_clipimage.py
┃ ┗ video_download.py
┣ README.md
┗ requirements.txt
```
## Usage



#### audio
- `audio_check_dB.py`: 특정 dB 값을 확인하여 사람의 음성 여부를 판별하는 스크립트입니다.
- `audio_dB_crop.py`: 오디오 파일에서 인간의 목소리 세그먼트를 추출하고 감지된 음성 세그먼트를 포함하는 새로운 오디오 파일을 10초로 자르는 스크립트입니다.
- `audio_wav_cropping.py`: JSON POINT에 맞춰 오디오를 자르는 스크립트입니다.

#### crawling

- `crawling_detect.py`: 비디오 클립에서 얼굴과 오디오를 감지하고 세분화하는 스크립트입니다.
- `crawling_rename_video.py`: 'download' 폴더에서 비디오 이름과 CSV의 인덱스를 맞추는 스크립트입니다.
- `crawling_select_csv.py`: 주어진 CSV 파일에서 YouTube ID를 찾아 해당하는 파일 이름에서 정보를 추출하고, 이 정보를 새로운 CSV 파일에 저장하는 간단한 데이터 처리 작업을 수행하는 스크립트입니다.
- `crawling_urlsave.py`: Selenium을 사용하여 YouTube 크롤링을 수행하여 약 162개의 비디오에 대한 이름, 제목 및 URL 정보를 Youtube_search_df.csv에 저장하는 스크립트입니다.
- `crawling_videosave.py`: '`crawling_urlsave.py`'를 통해 얻은 URL에서 비디오를 다운로드하는 스크립트입니다. 비디오는 'download' 폴더에 저장됩니다.

#### image

- `image_clipseg2.py`: CLIPSeg 모델을 사용하여 텍스트 프롬프트를 기반으로 이미지 세분화를 수행하는 스크립트입니다. 이미지를 불러와 텍스트 프롬프트로 처리하고, 식별된 객체를 기반으로 세분화된 이미지를 생성합니다.
- `image_face_frame.py`: 비디오에서 사람의 얼굴이 정면이고, 눈을 뜨고 있을 때 캡쳐하고 배경을 제거하는 스크립트입니다.

#### relabel

- `relabel_detect_getframe.py`: 주어진 비디오에서 얼굴을 감지하고, 감지된 얼굴에 대해 성별과 연령을 추정하여 화면에 표시하고, 일정한 간격으로 프레임을 캡처하여 이미지 파일로 저장하는 기능을 수행합니다.
- `relabel_select_csv.py`: 데이터 경로에서 YouTube ID를 추출하고, 파일 이름에서 필요한 정보를 추출하여 새로운 CSV 파일에 저장하는 스크립트입니다.
- `relabel_Vox_age.py`: 이미지 폴더에서 이미지들을 읽어와 각 이미지의 나이를 예측하고, 가장 흔한 나이 그룹을 세서 출력하고, 그 결과를 CSV 파일에 저장하는 작업을 수행합니다.

#### video

- `video_clipimage.py`: 주어진 이미지에서 얼굴을 감지하고, 감지된 얼굴 영역을 사각형으로 표시한 후 해당 얼굴을 256x256 크기로 조정하여 저장하는 작업을 수행합니다.
- `video_download.py`: 주요 기능은 주어진 YouTube 비디오 링크에서 비디오를 다운로드하고, 다운로드한 비디오를 mp4 또는 mp3 형식으로 변환하는 스크립트입니다.

#### total
- `total_audio_video_image.py`: 오디오, 비디오 및 이미지와 관련된 작업을 총 수행하는 스크립트입니다.
- `total_origin_remove.py`: 데이터 경로에서 원본 파일을 제거하는 스크립트입니다.




## Getting Started


### Setting up Vitual Enviornment


1. Initialize and update the server

```
su -
source .bashrc
```



2. Create and Activate a virtual environment in the project directory



```
conda create -n env python=3.8
conda activate env
```



4. To deactivate and exit the virtual environment, simply run:



```
deactivate
```



### Install Requirements



To Install the necessary packages liksted in `requirements.txt`, run the following command while your virtual environment is activated:

```
pip install -r requirements.txt
```


File renamed without changes.
107 changes: 107 additions & 0 deletions data/audio/audio_wav_cropping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
import json
from pydub import AudioSegment

def process_wav_and_json(wav_file: str, json_file: str, wav_file_name: str, save_folder: str):
""" wav 파일을 받아 json 에서 필요한 부분을 잘라내 형태에 맞게 저장할 코드
Args:
wav_file (str): json 파일과 매칭되는 wav_file 경로
json_file (str): wav_file croping에 사용될 json_file 경로
wav_file_name (str): folder명 지정에 사용할 wav_file 자체 이름
save_folder (str): 정제된 파일을 저장할 경로
"""
count = 1
audio = AudioSegment.from_wav(wav_file)

# 저장할 폴더 생성
wav_file_folder = wav_file_name.split("_")[:-2]
wav_file_folder = "_".join(wav_file_folder)
wav_file_folder = os.path.join(save_folder,'data', wav_file_folder,'audio')
os.makedirs(wav_file_folder, exist_ok=True)

# json 파일 열기
with open(json_file, 'r') as f:
data = json.load(f)
data= data[0]

# 각 시간대별로 돌아가며 동영상 croping
for sentence_info in data['Sentence_info']:
start_time = round(int(sentence_info['start_time']), 3)
end_time = round(int(sentence_info['end_time']), 3)
time = end_time - start_time
if time <3 or time > 10 :
continue

start_time_ms = start_time * 1000
end_time_ms = end_time * 1000


segment = audio[start_time_ms:end_time_ms]
output_wav_file = f"{wav_file_name.split('_')[-1]}_{count:03d}.wav"

output_wav_path = os.path.join(wav_file_folder, output_wav_file)

segment.export(output_wav_path, format='wav')
count += 1

print(f"Saved {output_wav_path}")


def find_matching_json(file_name: str, json_folder: str) ->str :
"""wav 파일과 파일명이 똑같은 json 파일을 찾아 경로 반환,
만약 없다면 None 반환
Args:
file_name (str): wav 파일 이름 가져오기
json_folder (str): json이 저장된 위치 확인
Returns:
str: wav 파일에 해당하는 json 파일 반환
"""

for root, dirs, files in os.walk(json_folder):
for file in files:
if file.split('.')[0] == file_name:
json_file = os.path.join(root, file)
return json_file
return None

def find_wav(wav_folder: str, json_folder: str, save_folder: str):
""" 처음 정제할 wav 파일 찾기
이후 json 파일을 찾아 wav를 정제한다.
Args:
wav_folder (str): wav 파일들이 저장된 폴더 위치
json_folder (str): json 파일들이 저장된 폴더 위치
save_folder (str): croping 된 파일들을 저장할 위치
"""

for root,_,files in os.walk(wav_folder):
for file in files:
if file.endswith('.wav'):
wav_file = os.path.join(root, file)
wav_file_name = wav_file.split('/')[-1].split('.')[0]
json_file = find_matching_json(wav_file_name, json_folder)

if json_file:
process_wav_and_json(wav_file, json_file, wav_file_name, save_folder)
os.remove(wav_file)


def main(wav_folder: str, json_folder: str, save_folder: str):
find_wav(wav_folder, json_folder, save_folder)
print('End of processing')




if __name__ == '__main__':
# WAV 파일이 들어있는 폴더 경로
wav_folder = '/home/carbox/Desktop/data/009.립리딩(입모양) 음성인식 데이터/01.데이터/2.Validation/원천데이터'
# JSON 파일이 들어있는 폴더 경로
json_folder = '/home/carbox/Desktop/data/009.립리딩(입모양) 음성인식 데이터/01.데이터/2.Validation/라벨링데이터'
# 원천데이터를 저장할 폴더 경로
save_folder = '/home/carbox'

main(wav_folder, json_folder, save_folder)
52 changes: 42 additions & 10 deletions data/crawling/crawling_select_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,72 @@
from argparse import ArgumentParser

def parse_args():
"""
Command-line arguments parser.
Returns:
argparse.Namespace: Parsed arguments.
"""
parser = ArgumentParser()

# Conventional args
parser.add_argument('--csv_file', type=str, default='output_test.csv')
parser.add_argument('--data_path', type=str, default='origin/video')
parser.add_argument('--save_csv', type=str, default='new_output.csv')
parser.add_argument('--csv_file', type=str, default='output_test.csv',
help="Path to the CSV file containing data.")
parser.add_argument('--data_path', type=str, default='origin/video',
help="Path to the directory containing files and folders.")
parser.add_argument('--save_csv', type=str, default='new_output.csv',
help="Path to save the new CSV file.")

args = parser.parse_args()

return args


def list_files_and_folders(data_path):
"""
List files and folders in the given directory path.
Args:
data_path (str): Path to the directory.
Returns:
list or None: List of files and folders if directory exists, otherwise None.
"""
if os.path.isdir(data_path):
items = os.listdir(data_path)
return items
else:
return None

def main(csv_file, data_path, save_csv):
"""
Main function to process data.
Args:
csv_file (str): Path to the CSV file.
data_path (str): Path to the directory containing files and folders.
save_csv (str): Path to save the new CSV file.
"""
# Read CSV file
csv_data = pd.read_csv(csv_file, header=None)

# Get list of files and folders in the data path
youtube_ids = list_files_and_folders(data_path)

# Process each YouTube ID
for youtube_id in youtube_ids:
# Filter rows corresponding to the YouTube ID
filtered_df = csv_data[csv_data[0].astype(str).str.contains(youtube_id)]
first_row = filtered_df.iloc[0:1]

# Extract information from file name
file_name = list_files_and_folders(os.path.join(data_path, youtube_id))[0]
file_name_list = file_name.split("_")
first_row[4] = file_name_list[0]
first_row[5] = file_name_list[1]

# Add extracted information as new columns
first_row[4] = file_name_list[0]
first_row[5] = file_name_list[1]

# Save to new CSV file
first_row.to_csv(save_csv, mode="a", index=False, header=False)


if __name__ == '__main__':
args = parse_args()
main(**args.__dict__)
main(**args.__dict__)
File renamed without changes.
Loading

0 comments on commit df4ff90

Please sign in to comment.