Thứ Tư, 19 tháng 3, 2014

Dựng phim tua nhanh thời gian (time-lapse) với Raspberry Pi

Dựng phim tua nhanh thời gian là một trong những thứ thú vị bạn có thể làm với Raspberry Pi. Tôi đánh cuộc bạn đã tìm thấy nhiều giải pháp ở đâu đó khác cho kỹ thuật này. Tuy nhiên, tôi viết hướng dẫn này vì giải pháp của tôi có nhiều ưu điểm mà không có trong các hướng dẫn khác, chẳng hạn: - Bạn có thể sử dụng module camera cho Raspberry Pi, hoặc một camera USB (hay webcam)
- Không yêu cầu kỹ năng lập trình, chỉ sử dụng các ứng dụng/tiện ích đã có
- Phần cứng dễ tìm, không có gì đặc biệt
- Ưu điểm quan trọng nhất: mã hóa video tăng tốc phần cứng, do đó bạn không cần phải chuyển các bức ảnh sang một máy tính khác để dựng thành phim. Sử dụng hướng dẫn này, Raspberry Pi có thể dựng phim nhanh hơn cả một chiếc MacBook!
- Dễ dàng tùy chỉnh cho thiết lập tua nhanh thời gian của riêng bạn
- Và cuối cùng, kỹ thuật tua nhanh thời gian ngược
Chúng ta hãy bắt đầu!

Giới thiệu
Theo Wikipedia, tua nhanh thời gian (time-lapse) là một kỹ thuật trong đó tần số mà các khung hình được chụp (tốc độ khung) thấp hơn nhiều so với tần số được sử dụng để xem các khung hình đó. Khi phát ở tốc độ bình thường, thời gian có vẻ trôi nhanh hơn.
Ý tưởng để dựng phim tua nhanh thời gian rất đơn giản: thay vì chụp các khung hình ở tốc độ bình thường (24, 25 hoặc 30 hình/giây là các chuẩn cho điện ảnh, truyền hình chuẩn PAL và truyền hình chuẩn NTSC), bạn chụp các khung hình ở tốc độ thấp hơn nhiều, sau đó ghép chúng lại thành phim ở tốc độ bình thường. Kỹ thuật tua nhanh thời gian thường được sử dụng để dựng những cảnh hoặc sự kiện diễn ra lâu trong thực tế.
Lấy ví dụ, giả sử chúng ta muốn dựng một đoạn phim có độ dài 1 phút cho một sự kiện diễn ra 1 giờ trong thực tế. Chúng ta chọn tốc độ của đoạn phim là 24 hình/giây. Do đó chúng ta cần chụp 24 x 60 = 1440 khung hình (ảnh). Tốc độ khung khi chụp do đó sẽ là 1440 hình/giờ hay 0,4 fps (hình/giây), tức cứ sau mỗi 2,5 giây chúng ta chụp một hình.
Độ phân giải cho đoạn phim được xác định bởi khả năng của camera và cả dự kiến của chúng ta. Giả sử là 1280x720.

Yêu cầu phần cứng
Trước hết, chúng ta cần Raspberry Pi phiên bản B. Tiếp theo chúng ta có thể sử dụng module camera cho Raspberry Pi, đây là một lựa chọn tốt. Tuy nhiên, do chúng ta chỉ sử dụng camera để chụp các ảnh tĩnh ở tốc độ thấp, nên một camera USB (webcam) cũng đạt yêu cầu. Nhiều webcam có thể cắm trực tiếp vào cổng USB của Raspberry Pi, nếu không thì sử dụng hub USB gắn ngoài có cấp điện. Hướng dẫn này sẽ đề cập cả hai trường hợp (module camera cho Raspberry Pi và webcam USB).
Nếu bạn cần quay phim ngoài trời ở những nơi không có điện lưới, một giải pháp đơn giản và kinh tế để cấp điện cho Raspberry Pi là 4 cục pin sạc kích thước AA (mỗi cục pin có điện áp 1.2V) qua các chân GPIO (chân +5V và chân GND).
Chúng ta cần kết nối Internet để cài đặt một số phần mềm cần thiết trước khi bắt đầu. Tôi giả sử bạn đã biết cách truy cập vào Raspberry Pi (qua bàn phím+màn hình hoặc qua ssh). Nếu sử dụng ssh, bạn có thể copy-paste các dòng lệnh trong hướng dẫn vào terminal.
Cuối cùng là thẻ nhớ SD đã cài đặt hệ điều hành Linux. Tôi sử dụng Raspbian trong hướng dẫn này. Dung lượng cần thiết cho thẻ SD tùy thuộc vào bạn muốn đoạn phim dài bao lâu, độ phân giải cũng như tốc độ của nó (24, 25 hay 30 fps), do đó tùy thuộc vào số lượng ảnh bạn sẽ chụp và độ phân giải của chúng. Công thức tính kích thước cho một ảnh không nén (.ppm) là (3 x chiều rộng x chiều cao + 16) byte, do đó một ảnh không nén độ phân giải 1280x720 sẽ có kích thước khoảng 2.8 MB. Nếu chọn định dạng ảnh nén (chẳng hạn .jpeg như trong hướng dẫn này) mỗi tập tin ảnh 1280x720 chỉ có kích thước dưới 100 KB. Nói chung thẻ nhớ SD 4GB là đủ cho hầu hết các trường hợp.

Chuẩn bị phần mềm
Chúng ta cần thực hiện hai bước để dựng phim tua nhanh thời gian trực tiếp trên Raspberry Pi:
- Bước 1: Chụp các ảnh tĩnh ở tốc độ đã định trước
- Bước 2: Ghép các ảnh tĩnh thành phim sử dụng bộ mã hóa video phần cứng của Raspberry Pi
Đã có nhiều cách trong nhiều hướng dẫn để thực hiện bước 1. Nhưng bước 2, chưa có cách nào… cho đến khi bạn đọc hướng dẫn này ;)
Để thực hiện bước 1, hướng dẫn này sẽ sử dụng raspistill cho module camera cho Raspberry Pi hoặc streamer cho webcam USB. raspistill đã có sẵn trong Raspbian, do đó chúng ta chỉ cần cài thêm streamer
sudo apt-get install streamer
Để thực hiện bước 2, chúng ta sẽ không sử dụng các công cụ phổ biến trên Linux như mencoder, ffmpeg, avconv do chúng không (hoặc chưa) hỗ trợ GPU của Raspberry Pi. Giải pháp duy nhất để mã hóa bằng phần cứng là sử dụng plugin OpenMAX trong gstreamer. Codec sẽ sử dụng là H264.
Chúng ta cần thêm một nguồn phần mềm mới vào Raspbian để cài đặt plugin OpenMAX. Chạy 3 lệnh sau đây trên Raspberry Pi (dán chúng vào terminal):
sudo sh -c 'echo deb http://vontaene.de/raspbian-updates/ . main >> /etc/apt/sources.list'

sudo apt-get update

sudo apt-get install libgstreamer1.0-0 liborc-0.4-0 gir1.2-gst-plugins-base-1.0 gir1.2-gstreamer-1.0 gstreamer1.0-alsa gstreamer1.0-omx gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-pulseaudio gstreamer1.0-tools gstreamer1.0-x libgstreamer-plugins-bad1.0-0 libgstreamer-plugins-base1.0-0
Kiểm tra lại kết quả cài đặt:
gst-inspect-1.0 | grep omx
Bạn sẽ thấy kết quả:
omx: omxh264enc: OpenMAX H.264 Video Encoder
omx: omxvc1dec: OpenMAX WMV Video Decoder
omx: omxmjpegdec: OpenMAX MJPEG Video Decoder
omx: omxvp8dec: OpenMAX VP8 Video Decoder
omx: omxtheoradec: OpenMAX Theora Video Decoder
omx: omxh264dec: OpenMAX H.264 Video Decoder
omx: omxh263dec: OpenMAX H.263 Video Decoder
omx: omxmpeg4videodec: OpenMAX MPEG4 Video Decoder
omx: omxmpeg2videodec: OpenMAX MPEG2 Video Decoder
Chú ý dòng đầu tiên omxh264enc. Đó là video encoder chúng ta sẽ sử dụng.

Bước 1: Chụp các ảnh tĩnh ở tốc độ đã định trước
- Đối với module camera cho Raspberry Pi:
Như đã tính toán trong phần giới thiệu, trong 1 giờ (3600000 ms) chúng ta chụp một bức ảnh cứ mỗi 2,5 giây (2500 ms). Lệnh
raspistill -o timelapse%04d.jpeg -tl 2500 -t 3600000
sẽ tạo ra 1440 ảnh (từ timelapse0001.jpeg đến timelapse1440.jpeg). Do chúng ta cần 1440 ảnh, chúng ta sử dụng mã định dạng %04d (số nguyên 4 ký tự)
- Đối với webcam USB:
streamer -t 1440 -r 0.4 -s 1280x720 -o timelapse0000.jpeg
trong đó -t là số lượng khung hình, -r là tốc độ khung (0,4 fps nghĩa là 2,5 giây mỗi hình) -s là độ phân giải
sẽ tạo ra 1440 ảnh (từ timelapse0000.jpeg đến timelapse1439.jpeg).

Bước 2: Ghép các ảnh tĩnh thành phim sử dụng bộ mã hóa video phần cứng của Raspberry Pi
Bây giờ bạn đã có các ảnh tĩnh. Bạn không cần chuyển chúng sang một máy tính khác để dựng thành phim. Raspberry Pi có thể dựng phim nhanh hơn cả cái máy tính đó, thậm chí khi bạn còn đang mất công chuyển ảnh sang máy tính khác thì phim đã dựng xong rồi! CPU của Raspberry Pi yếu, nhưng GPU của nó mạnh. Bài hướng dẫn này khai thác sức mạnh của GPU trên Raspberry Pi.
gst-launch-1.0 multifilesrc location=timelapse%04d.jpeg index=1 caps="image/jpeg,framerate=24/1" ! jpegdec ! omxh264enc ! avimux ! filesink location=timelapse.avi
sẽ dựng các ảnh từ timelapse0001.jpeg đến hết vào tập tin timelapse.avi. Thay đổi tham số index nếu bạn muốn bắt đầu từ một số khác, ví dụ index=100 sẽ bắt đầu dựng phim từ timelapse0100.jpeg. Bạn có thể thay đổi tốc độ khung 24/1 thành 25/1, 30/1 hay tốc độ khung của riêng bạn. Phim sẽ hoàn thành sau ít phút.
Để so sánh hiệu quả mã hóa, tôi đã tiến hành thử nghiệm. Dựng phim với độ phân giải 1280x720, 24 fps, codec H264 từ 1500 bức ảnh trên một máy tính Core Duo 2 GHz, 1 GB RAM mất 4 phút 15 giây, nhưng trên Raspberry Pi chỉ mất 2 phút 15 giây!
Chạy lệnh
sync
để Raspberry Pi ghi toàn bộ dữ liệu vào thẻ SD, tránh hỏng và mất dữ liệu. Bây giờ bạn có thể chép timelapse.avi ra khỏi Raspberry Pi qua ssh, hoặc đơn giản ngắt điện khỏi Raspberry Pi và lấy phim ra khỏi thẻ nhớ.
Bạn có thể đặt các lệnh trong bước 1 và bước 2 vào một tập tin .sh để tự động hóa toàn bộ quá trình dựng phim
Video bên dưới sẽ cho bạn thấy khái niệm tua nhanh thời gian (time-lapse)

Phụ lục: Tua nhanh thời gian ngược
- Tạo một thư mục để chứa các ảnh theo thứ tự đảo ngược:
mkdir timelapse_reverse
- Đổi tên hàng loạt, ảnh đầu tiên sẽ chuyển thành ảnh cuối cùng, ảnh thứ hai sẽ chuyển thành ảnh gần cuối cùng (ví dụ với 1440 ảnh, nếu bạn có số lượng ảnh khác, chỉ cần thay đổi số 1439 trong dòng lệnh bên dưới):
for i in {0..1439}; do ri=`expr 1439 - $i`; cp timelapse`printf %04d $i`.jpeg timelapse_reverse/timelapse`printf %04d $ri`.jpeg; done
- Dựng phim tua nhanh thời gian ngược:
gst-launch-1.0 multifilesrc location=timelapse_reverse/timelapse%04d.jpeg caps="image/jpeg,framerate=24/1" ! jpegdec ! omxh264enc ! avimux ! filesink location=timelapse_reverse.avi
Video tua nhanh thời gian ngược

Tôi hy vọng hướng dẫn này sẽ giúp bạn giải quyết một số vấn đề kỹ thuật trong việc dựng phim tua nhanh thời gian với Raspberry Pi. Bạn có thể kết hợp hướng dẫn này với những phát kiến của riêng bạn để cải tiến quá trình dựng phim. Không chỉ dựng cảnh tua nhanh thời gian của một thành phố nào đó, bạn có thể dựng nhiều đoạn phim tua nhanh thời gian ngược thú vị như hoa nở, cây mọc, phản ứng hóa học chậm, nhộng biến thành bướm, mây bay, ốc sên di chuyển… và nhiều hơn nữa, tùy vào khả năng sáng tạo của bạn! Chúc vui vẻ!
Hướng dẫn này được viết sau khi đã kiểm nghiệm thực tế. Phiên bản tiếng Anh (của cùng tác giả) có trên diễn đàn Raspberry Pi.

Không có nhận xét nào: