Skip to main content

Hiệu ứng ảnh - Image Animation

1. Giới thiệu

Hiệu ứng trình diễn hình ảnh (Image Animation) là thao tác thay thế điểm ảnh của ảnh này với ảnh kia, như là hiệu ứng động hiển thị giữa các slide trong Microsoft PowerPoint. Dưới đây là một số ví dụ về hiệu ứng trình diễn hình ảnh.

Để thực hiện được thao tác hiệu ứng trình diễn hình ảnh, ta cần có một số kiến thức cơ bản về biểu diễn ảnhthao tác trên điểm ảnh.

2. Các hiệu ứng trình diễn hình ảnh

Các hiệu ứng trình diễn hình ảnh, cần có 1 bước chuẩn bị chung như sau:

Bước 1: ĐỌC ẢNH VÀ CHUẨN HÓA KÍCH THƯỚC ẢNH

Đọc lần lượt các ảnh từ 1 folder để cùng nơi với đoạn code tạo nên hiệu ứng.

import cv2
import os
#Đọc ảnh
image1 = cv2.imread(r'C:\Đường\dẫn\đến\file\ảnh\một.jpg')
image2 = cv2.imread(r'C:\Đường\dẫn\đến\file\ảnh\hai.jpg')
#Xuất Ảnh ra màn hình:
cv2.imshow("Anh 1",image1)
cv2.imshow("Anh 2",image2)
cv2.waitKey(0)

Để chọn được các ảnh với nhau thì cả 2 ảnh phải có chung một kích thước. Để thay đổi kích thước ảnh, ta sử dụng hàm cv2.resize() với cú pháp như sau:

#lấy kích thước của ảnh:
h1,w1,c1 = img1.shape
h2,w2,c2 = img2.shape

#Lưu vào h chiều cao, w chiều rộng nhỏ nhất giữa 2 ảnh:
h=min(h1,h2)
w=min(w1,w1)

#Thay đổi kích thước ảnh theo w,h:
img1 = cv2.resize(img1,(w,h))
img2 = cv2.resize(img2,(w,h))

Bước 2: CÁCH THỰC HIỆN HIỆU ỨNG TRÌNH DIỄN

Sau đây là một số ký hiệu quy ước: X là tọa độ chiều rộng Y là tọa độ chiều cao Z là tọa độ chiều sâu

Tọa độ có thể bằng một khoảng [a:b]
VD: Image=[0:255,:,:] ([:] là lấy toàn bộ)

Để tạo hiệu ứng ảnh chuyển động, ta thay thế giá trị điểm ảnh tại tọa độ a của ảnh 1 bằng giá trị điểm ảnh tại tọa độ b của ảnh 2 theo một vị trí chuyển động nhất định (Tịnh tiến, Quay, Ghi đè,…) mà người lập trình muốn bằng cách chạy vòng lặp

VD: Image1[a:b,:,:] = Image2[c:d,:,:] với [a:b] = [c:d])
(Ex: Image1[0:10,:,:] = Image2[10:20,:,:])

Ví dụ về sử dụng chuyện động tịnh tiến và ghi đè Xuất những tấm ảnh ra màn hình sau mỗi vòng lặp, như vậy ta sẽ cảm thấy như chúng đang chuyện động. Để nâng cấp hiệu ứng hơn, việc giới hạn chiều ngang hoặc chiều cao để ghi đè hoặc tịnh tiến theo nhiều hướng, thì ta có thể tạo ra nhiều hiệu ứng khác. Bằng cách thay đổi cách chọn tọa độ của điểm ảnh mà ta có thể thực hiện hiệu ứng trình diễn theo nhiều cách khác nhau. Sau đây là một cách thực hiện một số hiệu ứng đơn giản trong PowerPoint như Cover, Comb, Push ,...

Tạo ảnh Gif

#vì range(0,w) nó chỉ lấy giá trị từ 0->w-1
#nếu muốn hiệu ứng diễn ra nhanh hơn thì có thể thay:
# - range(0,w+1)->range(0,w+1,Speed),
# - Speed càng lớn thì ảnh hiện càng nhanh
results=[]
Speed = 6
for D in range(0,w+1,Speed):
result=img1.copy()
#Code trình diễn ảnh
result[:,0:w-D,:] = img1[:,D:w,:]
result[:,w-D:w,:] = img2[:,0:D,:]
#Tạo gif
results.append(result)
#Luu gif
imageio.mimsave('Name.gif', results)

2.1 HIỆU ỨNG COVER

FROM RIGHT

Mô tả: Các giá trị điểm ảnh dần được thay thế bởi những giá trị của điểm ảnh bên phải điểm ảnh bị thay thế, những giá trị ảnh bị dư ra bởi việc thay thế điểm ảnh sẽ nhận giá trị của ảnh thứ 2 bằng cách tương tự.

  • Ý tưởng: Sử dụng phương pháp tịnh tiến
Speed = 6
for D in range(0,w+1,Speed):
result=img1.copy()
result[:,0:w-D,:] = img1[:,D:w,:]
result[:,w-D:w,:] = img2[:,0:D,:]
cv2.imshow("FR",result)
cv2.waitKey(0)

Minh họa kết quả sau khi đã thực hiện:

FROM LEFT:

Mô tả: Giống với FROM RIGHT nhưng những giá trị điểm ảnh sẽ được thay thế bằng giá trị điểm ảnh bên trái của điểm ảnh bị thay thế.

Speed = 6
for D in range(0,w+1,Speed):
result=img1.copy()
result[:,0:D,:]=img1[:,w-D:w,:]
result[:,D:w,:]=img2[:,0:w-D]
cv2.imshow("FL",result)
cv2.waitKey(10)

Minh họa kết quả sau khi đã thực hiện:

2.2 HIỆU ỨNG COMB

Mô tả: Cách thực hiện giống như hiệu ứng COVER, tuy nhiên sự khác biệt ở đây là xem kẽ hiệu ứng COVER FORM LEFT và COVER FROM RIGHT theo chiều cao.

  • Ý tưởng: Sử dụng phương pháp tịnh tiến

Line là số dòng mà ta muốn chia ra.

Line = 6 # Chia ra thành 6 dòng
h1 = h1 // Line
Speed = 6
for D in range(0, w + 1, Speed):
for L in range(0, Line,2):
result[h1*L:h1*(L+1), 0:D, :] = img1[h1*L:h1*(L+1), w - D:w, :]
result[h1*L:h1*(L+1), D:w, :] = img2[h1*L:h1*(L+1), 0:w - D]
result[h1*(L+1):h1*(L+2), 0:w - D, :] = img2[h1*(L+1):h1*(L+2), D:w, :]
result[h1*(L+1):h1*(L+2), w - D:w, :] = img1[h1*(L+1):h1*(L+2), 0:D, :]
cv2.imshow("Comb", result)
cv2.waitKey(10)

Minh họa kết quả sau khi đã thực hiện:

2.3 HIỆU ỨNG PUSH

Mô tả: Ở hiệu ứng PUSH cách hoạt động cũng giống y hệt COVER những theo chiều cao từ dưới đi lên.

  • Ý tưởng: Sử dụng phương pháp tịnh tiến
Speed = 6
for D in range(0,h+1,Speed):
result=img1.copy()
result[0:h-D,:,:]=img1[D:h,:,:]
result[h-D:h,:,:]=img2[0:D,:,:]
cv2.imshow("Push",result)
cv2.waitKey(10)

Minh họa kết quả sau khi đã thực hiện:

2.4 HIỆU ỨNG UNCOVER

Mô tả: Thay thế giá trị điểm ảnh của ảnh 1 bằng giá trị điểm ảnh của ảnh 2 từ bên phải, và những giá trị đó cũng sẽ bị thay thế bới giá trị điểm ảnh bên phải điểm ảnh bị thay thế.

  • Ý tưởng: Sử dụng phương pháp tịnh tiến
Speed = 6
for D in range(0,w+1,Speed):
result=img1.copy()
result[:,0:w-D,:] = img1[:,D:w,:]
result[:,w-D:w,:] = img2[:,w-D:w,:]
cv2.imshow("Uncover",result)
cv2.waitKey(10)

Minh họa kết quả sau khi đã thực hiện:

2.5 HIỆU ỨNG SPLIT

Mô tả: Cách hoạt động giống UNCOVER, tuy nhiên ở đây sẽ bắt đầu thay thế những giá trị điểm ảnh từ giữa dần ra 2 bên.

  • Ý tưởng: Sử dụng phương pháp tịnh tiến
Speed = 6
for D in range(0,w//2,Speed):
result=img1.copy()
result[:,w//2-D:w//2+D,:] = img2[:,w//2-D:w//2+D,:]
result[:,0:w//2-D,:] = img1[:,0:w//2-D ,:]
result[:,w//2+D:w,:] = img1[:,w//2+D:w,:]
cv2.imshow("Split",result)
cv2.waitKey(10)

Minh họa kết quả sau khi đã thực hiện:

Tổng kết

Qua bài viết này bạn có thể làm những hiệu ứng trình diễn ảnh khác nhau, biết thêm những cách xử lý với điểm ảnh và tạo ảnh gif.

Tác giả: Phạm Văn Nghĩa