Gắn râu Yua Mikami – Phần 3: Kết hợp Face Detection + Image Processing và… Toán Học

Series này gồm 3 phần:

  1. Cơ chế hoạt động của các filter Snapchat và Facebook Messenger
  2. Làm quen với các thư viện và API cần sử dụng
  3. Gắn râu bằng cách kết hợp Face Detection + Image Processing và… Toán Học

 

Sau 2 phần trước, chúng ta đã tìm hiểu về cơ chế các filter hoạt động, cũng như cách dùng thư viện để gắn râu vào ảnh.

Tuy nhiên, kết quả vẫn chưa được như mong muốn, chúng ta được tấm hình dị hợm như sau.

Để ghép râu cho khớp và đẹp, chúng ta cần phải:

  1. Xác định được độ dài hàm râu
  2. Tìm vị trí đặt râu cho phù hợp

Đây là lúc chúng ta sử dụng lại công nghệ Face Detection ở phần 1 để xác định những điều trên. Cùng bắt đầu thôi nào!

Khi Face Detection kết hợp với Image Processing

Để gắn râu và đúng cách, ta xác lập những điều kiện sau:

  1. Địa điểm hợp lý để gắn râu là … phía trên môi (position)
  2. Độ dài của râu nên dài bằng môi (length)

Trước tiên, ta xem lại các landmark có thể được API nhận diện.

Các bạn bấm vào hình để xem ảnh lớn cho rõ nhé

 

Dựa theo tấm hình trên, ta thấy có thể sử dụng 2 landmarks là mouthLeftmouthRight (Chấm đỏ trong hình) để xác định 2 điều cần tìm.

Ngắm 2 điểm landmark chứ đừng ngắm 2 quả bưởi phía dưới nhe

Nhìn vào hình vẽ, ta dễ thấy:

  • Chiều dài bộ râu sẽ bằng khoảng cách giữa 2 điểm, tức x2 – x1.
  • Môi trái nằm phía trên, ta có thể đặt bộ râu ở vị trí của landmark mouthLeft, xích lên trên một chút. Tọa độ cụ thể sẽ là (x1, y2)

Sửa lại code mộy chút nào (Hàm detectImage chúng ta đã viết trong phần 1 nhé:

Kết quả thu được cũng tạm chấp nhận được:

Trông cũng khá cute rồi đấy nhỉ??

Khi gắn râu cũng cần dùng đến… hình học

Kết quả thu được chưa đẹp lắm, vì em Yua Mikami nghiêng đầu cute, trong khi hàm râu của chúng ta thẳng băng vuông góc.

Chúng ta đã hoàn toàn quên mất góc nghiêng của bộ râu!!

Đây là lúc chúng ta sử dụng kiến thức Toán Học và hình học thu được qua 12 năm trời để tính toán địa điểm và góc độ đặt râu hợp lý lên mặt bé Yua dễ thương.

Chúng ta quay lại hình ban đầu để tính toán nhé.

  1. Lần lượt gọi A, B, C là các điểm nhưng trong hình, A là giao điểm của 2 đường thằng x2 và y1. Tam giác ABC vuông tại A.
  2. Nhìn kĩ ta, sẽ thấy chiều dài của râu không phải là x2 – x1 (AC) mà là độ dài đoạn BC (cạnh huyền)
  3. Bộ râu sẽ nghiêng 1 góc bằng với góc ACB
  4. Theo toán học: tan = đối/kề => tan ACB = AB/AC. Tính toán ta sẽ tìm ra được góc ACB.
  5. Để phù hợp, râu nên  được đặt ở giữa môi (landmark upperLipTop), dịch lên khoảng 1/2 về phía mũi (landmark noteTip)

Sửa lại mấy dòng code một xíu nhé:

Kết quả thu được khá là ưng ý <3.

Các bạn thấy chưa, chỉ một phép gắn râu đơn giản mà chúng ta phải vận dụng một số kiến thức Toán rồi đấy! Ai bảo lập trình không cần nhiều đến Toán đâu nào?

Trong lĩnh vực Image Processing, toán học còn được vận dụng rất nhiều nữa cơ! Ví dụ như chuyển ảnh trắng đen, filter màu … đôi khi phải dùng đến các phép Toán ma trận nữa đấy.

Code của chúng ta hiệu quả tới mức nào?

Sau một hồi code mệt mỏi, chúng ta đã có một đoạn code cho kết quả khá ưng ý.

Tuy nhiên, code của chúng ta chạy tốt với tấm ảnh Yua Mikami không có nghĩa nó sẽ chạy tốt với những tấm hình khác!!

Do vậy, chúng ta thử thay url của ảnh khác vào và chạy lại code nha!

Kết quả cũng khá là ok đấy chứ nhỉ? Hihi, code của mình code mà lại!

Mở rộng thêm

Các bạn có thể mở rộng thêm với các filter đội vòng hoa, đeo kính, gắn tai thỏ:

  • Vòng hoa: Nằm ngay phía trên trán, độ cao bằng trán, vòng hoa dài hơn bề ngang khuôn mặt một chút
  • Đeo kính: Nằm ngay mắt, độ dài bằng bề ngang khuôn mặt
  • Tai thỏ: Khó hơn, có thể dùng mũi chia mặt ra làm 2 phần, đặt hai tai tại 2 trung điểm.

Sau một hồi sửa chữa, chúng ta có hàm addFlower để gắn vòng hoa lên trán. Các bạn thấy đấy, để xác định tọa độ của trán, ta phải biết về  kết cấu khuôn mặt + nhân tướng học mới tính được.

Kết quả cũng không đến nỗi nào.

Mũi ngắn làm phép tính hơi lệch :))

 

Tuy nhiên, chỉ cần một phát nghiêng đầu cute của bé Yua Mikami cũng khiến vòng hoa đặt lệch ngay!

Lúc này các bạn sẽ phải tính lại góc nghiêng của vòng, vị trí đặt vòng cũng sẽ di chuyển theo góc nghiêng của đầu nhé!

Đến đây thì mình hơi lười rồi nên để phần này làm bài tập cho bạn đọc vậy! Gợi ý nha, bạn có thể tìm góc nghiêng của đầu dựa theo góc nghiêng giữa 2 mắt hay 2 bên môi nha.

Kết

Vậy là sau 3 phần, chúng ta đã hoàn thành ứng dụng Gắn Râu Sơn Tùng, biến tướng thành Gắn Râu cho JAV Idol, sử dụng NodeJS. Chúc mừng bạn đã cùng mình đi hết 3 phần của series.

Ban đầu, mình định viết luôn hướng dẫn cách tách ảnh gif và ghép lại luôn, nhưng phần nào không hay ho mấy nên mình bỏ qua hihi.

Để gắn râu những tấm có nhiều khuôn mặt, cần sửa code một chút. Xem như đây là bài tập cho bạn đọc nhé 😀

Các bạn thấy đấy, đằng sau một tính năng tưởng chừng đơn giản (filter thêm râu, thêm vòng hoa) là hàng đống những kĩ thuật phức tạp từ face recognition, image processing cho tới hình học toán học nhân tướng học! Ngạc nhiên chưa?

 

Bạn nào có những câu hỏi tương tự về những tính năng “hay ho” trên app mà mình sử dụng thì cứ để lại comment nha. Nếu thú vị hay mình sẽ cùng các bạn nghiên cứu thử.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s