Keyframe trong Video

Keyframe là gì?

Trong thế giới video, keyframe đóng vai trò như những “nốt nhạc” chủ đạo trong một bản nhạc, là những khoảnh khắc quan trọng đánh dấu sự thay đổi lớn hoặc điểm nhấn của nội dung. Đặc biệt trong nén video, keyframe là những khung hình độc lập, không cần dựa vào bất kỳ khung hình nào khác để tái tạo, giúp chúng trở thành nền tảng cho việc phân tích và xử lý video.

-> Hiểu đơn sơ là keyframe là nhưng frame mang tất cả nội dung của video, nhưng có độ nén cao và dung lượng ít hơn so với video gốc. (như giáo trình giải tích của thầy Bùi Xuân Diệu, nội dung chính là các trang có chứa công thức)

Tại sao việc extract keyframe lại quan trọng?

Hãy tưởng tượng bạn có một video dài vài giờ đồng hồ, nhưng chỉ cần một vài khoảnh khắc để nắm bắt nội dung chính. Đó chính là lúc việc extract keyframe trở thành công cụ đắc lực. Keyframe giúp bạn nắm bắt cốt lõi của video mà không cần phải xem toàn bộ, từ việc tạo ra các bản tóm tắt ngắn gọn đến việc phân tích sâu hơn nội dung video.

-> Nhìn mấy ông cháu đọc vài phút xong quyển sách bằng cách lướt vèo vèo vèo, làm mình hoảng, chắc do mắt họ có model xử lý và bắt keyframe với độ chính xác cực cao :0

Các Phương Pháp Extract Keyframe: Chọn Lọc Khoảnh Khắc Đắt Giá

Dựa trên thời gian:
Một cách tiếp cận đơn giản và hiệu quả là chọn keyframe theo các khoảng thời gian nhất định. Phương pháp này rất hữu ích khi bạn cần nắm bắt toàn cảnh của video mà không quan tâm quá nhiều đến chi tiết cụ thể.

Dựa trên sự thay đổi nội dung:
Để tăng độ chính xác, bạn có thể chọn keyframe dựa trên những thay đổi nổi bật giữa các khung hình liên tiếp. Ví dụ, khi có sự thay đổi lớn về màu sắc, hình dạng, hoặc chuyển động, đó chính là những khoảnh khắc bạn nên lưu giữ lại.

Sử dụng thuật toán Machine Learning:
Nhờ vào sự phát triển của trí tuệ nhân tạo, bạn có thể sử dụng các mô hình học máy để tự động chọn ra những keyframe quan trọng nhất. Các mô hình này có khả năng nhận diện những đối tượng, hành động hoặc sự kiện đặc biệt trong video, giúp bạn không bỏ lỡ bất kỳ chi tiết nào.

Ngoài mấy cái trên ở các cõi mạng thì tôi sẽ giới thiệu một cái về tasks mà tôi đang nghiên cứu, giới thiệu cho mọi người coi thử.

Chung quy lại thì mấy thuật toán này thường gọi là Frame Difference Method - Algo, tùy vào các yêu cầu và video thì người ta xào lại cho hợp lý.

Thuật toán 1: Tôi nghĩ là tốt nhất trong trường hợp của tôi đang gặp hiện tại

Ứng với các video tin tức

  1. Bắt đầu: Đọc video đầu vào (lấy từng frame), đặt giá trị ngưỡng (threshold), và thiết lập khung hình ban đầu (initial frame) là None.
  2. Lặp:
    Lặp qua từng frame của video:

Đọc frame hiện tại.

Chuyển frame hiện tại sang ảnh xám.

  • Nếu frame trước đó là None:
  • Lưu frame hiện tại làm keyframe đầu tiên.
  • Gán frame hiện tại là frame trước đó.

Tiếp tục vòng lặp.

Tính toán sự khác biệt giữa frame hiện tại và frame trước đó.

Tính giá trị trung bình của sự khác biệt.

Nếu giá trị trung bình lớn hơn ngưỡng:

  • Lưu frame hiện tại làm keyframe.
  • Gán frame hiện tại là frame trước đó.
  1. Kết thúc vòng lặp.

  • Nguyên lý cơ bản: Tìm những Frame có thay đổi đáng kể so với frame trước đó
  • Chuyển sang ảnh sám để giảm tốc độ tính toán.
  • Tính toán sự khác biệt: trị tuyệt đối của 2 vector frame, k – 1, k.
  • Threshold: giá trị quyết định độ nhạy của thuật toán, quá cao sẽ làm mất mát nhiều thông tin.

  • Ưu điểm: đơn giản, hiệu quả cho nhiều video, xử lý được cho nhiều video, có thể real – time tốt
  • Hạn chế: Không hiệu quả cho các video có chuyển động liên tục. Như video review đế chế thì thuật toán này hoàn toàn ăn hại nha :))

Về code:

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
32
33
34
35
36
37
38
39
40
import cv2
import numpy as np

def extract_keyframes(video_path, threshold=25):
cap = cv2.VideoCapture(video_path)

ret, prev_frame = cap.read()
prev_frame_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)

keyframes = [prev_frame]
frame_count = 0

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

frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

diff = cv2.absdiff(frame_gray, prev_frame_gray)

mean_diff = np.mean(diff)

if mean_diff > threshold:
keyframes.append(frame)

prev_frame_gray = frame_gray
frame_count += 1

cap.release()
return keyframes

video_path = 'AOE.mp4'

keyframes = extract_keyframes(video_path)

for i, frame in enumerate(keyframes):
cv2.imwrite(f"keyframe_{i}.jpg", frame)

print(f"Đã trích xuất {len(keyframes)} keyframe.")

Xem mấy cái mà tôi test nè:
Đầu vào là một video về Taxi công nghệ ở Trung Quốc đang làm mưa làm gió trong thị trường dịch vụ xe, các tài xế có nguy cơ bị mất việc do máy móc, ai thay thế.

Muốn coi thì đây: https://www.youtube.com/watch?v=aBLSQdQzEXw&t=1s

Đó thì khi mà chạy thuật toán với 2361 frame (video 1p31s) và threshold = 30 thì cho ra 12 keyframes:

Sau khi xem đi xem lại video 10 lần và bằng việc kiểm thử bằng mắt thì tôi thấy keyframes khá ok:

Các để chọn ngưỡng, tôi chạy lại thuật toán với nhiều ngưỡng khác nhau và viết các hàm để tính toán các chỉ số như độ phủ, tỉ lệ nén, độ đa dạng thì cho ra threshold = [27, 30] là đẹp.

Ae mà áp dụng thuật toán này cho cái video về AOE thì nó chỉ cho ra có 2 frame và mất mát nhiều thông tin (threshold = 30). Vì vậy những video có nhiều hành động thì thuật toán này phế :))).

Thuật toán 2:

Tương tự như cái trên nhưng có thêm bước tiền xử lý tăng độ tương phản cho ảnh và lặp với frame k - 1, k, k+1. Lấy giao của của {fk, fk-1}, {fk, fk+1}.

Rồi so sánh với ngưỡng để pick keyframe. Cái này chạy chậm hơn cái trên

Thuật toán 3: Dùng KMeans

Nghe khá là vô lý nhưng mà ý tưởng thì tuyệt vời v ò:

  • Đầu tiên, giảm số chiều của các khung hình video bằng cách sử dụng phương pháp phân tích thành phần chính (PCA). Do là Kmeams kém hiệu quả đối với các dữ liệu có nhiều chiều nên ta phải dùng pca để giảm số chiều đi để tạo thành các điểm trong không gian 2 chiều.

  • Thứ hai, phân cụm dữ liệu bằng cách sử dụng k-means để tìm các nhóm khung hình chính duy nhất


  • Sử dụng k=8 để xác định 8 khung hình chính từ video để gán nhãn. (cái này dùng Elbow để xác định nha)

-> Túm lại là trông nó khá là rườm rà và đúng như vậy thuật toán này khá phế và chạy thì cực lâu do độ phức tạp của Kmeans là cực kỳ lớn. (Tôi thuyết trình về Kmeans xong bị thầy hành nhiều rồi nên biết :)))

Ai muốn tìm hiểu kĩ hơn thì xem ở đây nha!

Các công cụ hỗ trợ

OpenCV: Thư viện mạnh mẽ cho computer vision, về độ hót thì khỏi phải nói, từ lúc tôi học python tôi đã nghe về thư viện này. Ngày xưa tôi đam mê computer vision lắm (tôi sẽ không nói là tôi mê CV từ lúc tôi nhìn thấy job CV Engineer 5 year with salary 15k $ đâu :>). Túm lại là thư viện này có tất cả những cái cần thiết và các thuật toán tối ưu

Ứng Dụng Thực Tế: Khi Keyframe Làm Nên Chuyện Lớn

Tóm tắt video:

Thay vì xem cả video dài hàng giờ, keyframe giúp bạn tạo ra những bản tóm tắt ngắn gọn và cô đọng. Học kiến thức một cách nhanh chóng mà chả cần phải ngồi để xem hết video.

Phân tích nội dung video:

Bạn có từng nghĩ là nó có thể biết được video có ý nghĩa như nào chưa. Bạn bị mất trộm một đồ vật quan trọng mà bạn chỉ nhớ những chi tiết quan trọng trong cái thời gian bạn bị mất (nhà bạn có camera ghi lại video). Bạn muốn tìm lại thông tin ấy, ví dụ lúc ấy có bạn zai nào đó mặc áo màu đỏ đi ngang qua. Thì ta có thể dễ dàng truy vấn lại đoạn video đó. Và tìm lại được đồ bị mất.

-> Hay v ò ae ạ.

Tạo thumbnails:

như cái tôi đang nghiên cứu thì cái thumbnails này quan trọng lắm nha.
Các nền tảng video như YouTube sử dụng keyframe để tạo thumbnails - những hình ảnh thu nhỏ đại diện cho video. Một thumbnail hấp dẫn thường là một keyframe thể hiện nội dung nổi bật nhất của video.

Thách Thức và Giải Pháp: Làm Thế Nào Để Chọn Keyframe Tốt Nhất?

Chọn keyframe đúng:

Đôi khi việc chọn đúng keyframe là một thách thức lớn, đặc biệt với những video có nội dung phức tạp hoặc thay đổi liên tục. Giải pháp là sử dụng các phương pháp kết hợp hoặc ứng dụng machine learning để tối ưu hóa quá trình này.

Hiệu suất xử lý:

Với những video dài hoặc có độ phân giải cao, việc extract keyframe có thể tiêu tốn nhiều tài nguyên. Sử dụng các công cụ tối ưu như FFmpeg hoặc triển khai xử lý trên GPU có thể giúp giải quyết vấn đề này.

Gợi Ý Đọc Thêm

Nếu bạn muốn tìm hiểu thêm về chủ đề này, đây là một số tài liệu và khóa học có thể hữu ích:

Computer Vision: Algorithms and Applications - Richard Szeliski
Digital Video Processing - A. Murat Tekalp
Learning OpenCV - Gary Bradski and Adrian Kaehler