유투브 동영상 올리면 썸네일 어떤거 할거냐고 고르라고 동영상에서 이미지들 몇개 캡쳐해서 주르륵 보여주잖아요. 이번시간에는 동영상에서 키프레임을 추출하는 코드를 작성해보도록 하겠습니다. 이렇게 추출한 이미지들을 아바타로 활용하면 아무래도 여기저기서 따로 찍은 사진들을 조합해서 만드는 것보다 자연스럽고 일관된 모습의 아바타를 만들수 있기때문에 동영상에서 아바타에 사용할 이미지를 추출하는것을 추천드립니다.
동영상파일을 읽어오는데 필요한 라이브러리는 moviepy입니다. 필요한 라이브러리를 설치해주세요.
pip install moviepy pillow
extract_keyframes.py이라는 파일을 하나 생성해주세요. 그리고 해당라이브러리와 출력파일을 저장하기 위해 필요한 os도 코드에 포함시켜주세요.
import os
from moviepy import VideoFileClip
from PIL import Image
이제 키프레임을 추출할 동영상을 변수에 담습니다
video_path = 'video2.mp4'
그리고 동영상에서 이미지를 많이 추출해달라고 요청하는 경우에 대비해서 추출한 이미지파일들을 frames라는 폴더안에 생성하도록 할게요.
output_frame_dir = 'frames'
이제 동영상에서 키프레임을 추출하는 함수를 만들어 보도록 하겠습니다. 이 함수는 동영상경로와 저장할 폴더위치, 그리고 추출하고자하는 프레임갯수를 인자로 넘겨받고 동영상을 읽어서 해당위치에 필요한 갯수만큼의 키프레임 캡쳐하여 지정한 폴더에 이미지로 저장해줄겁니다.
def extract_frames( video_path, output_dir, num_frames=10 ):
일단 VideoFileClip()함수에 인자로 받은 동영상경로를 넘겨주어 비디오 클립 Object를 받아옵니다. 해당 동영상의 길이가 얼마나 되는지를 봐서 생성하고 싶은 키프레임으로 나누어 주면 어느정도 간격으로 프레임을 추출해야 동영상 전반에 걸쳐 고르게 추출할수 있는지가 나오겠죠.
clip = VideoFileClip(video_path)
duration = clip.duration
interval = duration / num_frames
이미지를 저장할 경로가 존재하지 않으면 에러가 나니까 폴더가 없으면 만들어 줍니다.
if not os.path.exists(output_dir):
os.makedirs(output_dir)
동영상에서 이미지를 가져오는 방법은 클립 object의 get_frame()함수에게 어느시간대의 프레임을 가져오라고 하면 얘가 배열을 반환합니다. 그러면 Image.fromarray()함수로 배열을 이미지로 변환해서 지정된 폴더에 저장을 합니다.
for i in range(num_frames):
frame_time = i * interval
frame = clip.get_frame(frame_time)
frame_image = Image.fromarray(frame)
frame_image.save( f" {output_dir} /frame_ {i} .jpg" )
완성된 코드는 다음과 같습니다.
import os
from moviepy import VideoFileClip
from PIL import Image
# 비디오에서 프레임을 추출하는 함수
def extract_frames(video_path, output_dir, num_frames=10):
clip = VideoFileClip(video_path)
duration = clip.duration
interval = duration / num_frames
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for i in range(num_frames):
frame_time = i * interval
frame = clip.get_frame(frame_time)
frame_image = Image.fromarray(frame)
frame_image.save(f"{output_dir}/frame_{i}.jpg")
# 프레임 추출 함수 호출
video_path = 'video1.mp4'
output_frame_dir = 'frames'
extract_frames(video_path, output_frame_dir)
그러면 파일을 실행해보도록 하겠습니다. 실행하기 전에 동영상파일을 하나 가져다가 같은 폴더에 저장합니다.

그리고 스크립트를 실행하면
python extract_keyframes.py
다음과 같이 frames라는 폴더 안에 10개의 키프레임이 이미지로 저장이 됩니다.
