Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android
Code

Nhận biết mọi người với SDK Snapdragon của Qualcomm

by
Difficulty:AdvancedLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Thai An (you can also view the original English article)

Cách đây không lâu thì việc chụp ảnh khá tốn kém. Máy ảnh yêu cầu quay phim với dung lượng giới hạn và việc xem kết quả cũng cần thêm thời gian và nhiều tiền hơn. Những hạn chế cố hữu này đảm bảo rằng chúng tôi đã chọn lọc với những bức ảnh chúng tôi đã chụp.

Tiến nhanh đến ngày hôm nay và những hạn chế này đã được đẩy lùi nhờ vào công nghệ, nhưng chúng ta hiện đang phải đối mặt với một vấn đề mới, lọc, sắp xếp và chọn ra những bức ảnh quan trọng từ nhiều bức ảnh chúng ta chụp.

Vấn đề mới này là điều truyền cảm hứng cho hướng dẫn này. Trong đó, tôi sẽ chứng minh cách chúng ta có thể sử dụng các công cụ mới để giúp làm cho công việc của người dùng dễ dàng hơn bằng cách giới thiệu các phương pháp mới để lọc và tổ chức nội dung của chúng tôi.

1. Khái niệm

Đối với dự án này, chúng tôi sẽ cân nhắc một cách lọc khác thông qua bộ sưu tập ảnh của bạn. Đồng thời, bạn sẽ tìm hiểu cách tích hợp và sử dụng SDK Snapdragon của Qualcomm để xử lý và nhận dạng khuôn mặt.

Chúng tôi sẽ cho phép người dùng lọc một bộ ảnh theo danh tính. Bộ sưu tập sẽ được lọc theo danh tính từ một bức ảnh mà người dùng chạm vào, như được minh họa dưới đây.

Wireframes of the application showing a master detail pattern

2. Tổng quan

Trọng tâm chính của bài viết này là giới thiệu việc xử lý và nhận dạng khuôn mặt bằng cách sử dụng Snapdragon SDK của Qualcom, với hy vọng gián tiếp khuyến khích cách suy nghĩ mới và sử dụng các metadata (siêu dữ liệu) có nguồn gốc từ nội dung.

Để tránh bị cố định trong hệ thống, tôi đã tạo một template để cung cấp dịch vụ cơ bản để quét qua bộ sưu tập ảnh của người dùng và một lưới để hiển thị ảnh. Mục tiêu của chúng tôi là tăng cường template này với khái niệm được đề xuất ở trên.

Trong phần sau, chúng tôi sẽ cân nhắc một cách ngắn gọn các thành phần này trước khi chuyển sang giới thiệu Snapdragon SDK của Qualcomm.

3. Khung sườn

Như đã đề cập ở trên, mục tiêu của chúng tôi là tập trung vào Snapdragon SDK vì vậy tôi đã tạo ra một khung sườn có tất cả các hệ thống được triển khai. Dưới đây là sơ đồ và mô tả về dự án, hỗ trợ tải xuống từ GitHub.

Component model for the application broken down into Presentation Service and Data layers

Gói data của chúng tôi chứa triển khai SQLiteOpenHelper (IdentityGalleryDatabase) chịu trách nhiệm tạo ra và quản lý cơ sở dữ liệu của chúng tôi. Cơ sở dữ liệu sẽ bao gồm ba bảng, một bảng đóng vai trò là pointer dẫn tới bản ghi phương tiện (photo), một bảng khác để nhận dạng (identity) được phát hiện và cuối cùng là bảng về quan hệ kết nối danh tính với ảnh của chúng (identity_photo).

Highlevel database schema - 3 tables of photo identity and a relationship table identity_photo

Chúng tôi sẽ sử dụng bảng identity để lưu trữ các thuộc tính do Snapdragon SDK cung cấp, được trình bày chi tiết trong phần sau của hướng dẫn này.

Trong gói data cũng bao gồm Provider (IdentityGalleryProvider) và Contract (IdentityGalleryContract), nó không gì khác hơn là Provider tiêu chuẩn đóng vai trò là wrapper của class SQLiteOpenHelper.

Để cho bạn biết cách tương tác với class Provider, đoạn code sau được lấy từ class TestProvider. Giống như tên gọi, nó được sử dụng để kiểm tra class Provider.

Gói service chịu trách nhiệm lặp lại, lập danh mục và cuối cùng là xử lý các hình ảnh có sẵn thông qua MediaStore. Service mở rộng IntentService như một cách dễ dàng để thực hiện xử lý trên luồng của chính nó. Công việc thực tế được giao cho GalleryScanner, đây là class chúng tôi sẽ mở rộng để xử lý và nhận dạng khuôn mặt.

GalleryScannerIntentService này được khởi tạo mỗi khi MainActivity được tạo ra khi gọi lệnh sau:

Khi bắt đầu, GalleryScannerIntentService tìm nạp ngày scan cuối cùng và chuyển nó vào hàm constructor của GalleryScanner. Sau đó, nó gọi phương thức scan để bắt đầu lặp qua nội dung của nhà cung cấp dịch vụ MediaItem cho các mục sau ngày scan gần nhất.

Nếu bạn xem xét phương thức scan của class GalleryScanner, bạn sẽ nhận thấy rằng nó khá dài dòng, không có gì phức tạp xảy ra ở đây. Phương thức cần truy vấn các file cho phương tiện được lưu trữ bên trong (MediaStore.Images.Media.INTERNAL_CONTENT_URI) và bên ngoài (MediaStore.Images.Media.EXTERNAL_CONTENT_URI). Sau đó mỗi mục được chuyển đến một phương thức hook, đó là nơi chúng ta sẽ viết code để xử lý và nhận dạng khuôn mặt.

Hai phương thức hook khác trong class GalleryScanner có sẵn cho chúng tôi (như tên phương thức gợi ý) để khởi tạo và tái khởi tạo đối tượng FacialProcessing.

Gói cuối cùng là gói presentation. Như tên gọi, nó lưu trữ class Activity chịu trách nhiệm việc hiển thị thư viện của chúng tôi. Gallery là một GridView được đính kèm với một CursorAdapter. Như đã giải thích ở trên, chạm vào một mục sẽ truy vấn cơ sở dữ liệu cho bất kỳ ảnh nào có chứa một trong các danh tính của ảnh đã chọn. Ví dụ: nếu bạn chọn ảnh của Lisa và bạn trai Justin của cô ấy, truy vấn sẽ lọc tất cả các ảnh có chứa một hoặc cả Lisa và Justin.

4. SDK Snapdragon của Qualcomm

Để giúp các nhà phát triển khiến phần cứng của họ trông tuyệt vời, Qualcomm đã phát hành một bộ SDK tuyệt vời, một trong số đó là Snapdragon SDK. Snapdragon SDK trưng bày một nhóm chức năng được tối ưu hóa để xử lý khuôn mặt.

SDK được chia thành hai phần, xử lý và nhận dạng cho khuôn mặt. Do không phải tất cả các thiết bị đều hỗ trợ cả hai tính năng (hoặc một trong số đó), đây có thể là lý do khiến các tính năng này tách biệt, SDK cung cấp một cách dễ dàng để kiểm tra các tính năng mà thiết bị hỗ trợ. Chúng tôi sẽ đề cập đến điều này chi tiết hơn sau.

Quá trình xử lý khuôn mặt cung cấp phương pháp trích xuất các tính năng từ ảnh (của khuôn mặt) bao gồm:

  • Blink Detection (phát hiện nháy mắt): Đo mức độ mở rộng của mỗi mắt.
  • Gaze tracking (theo dõi ánh nhìn): Đánh giá nơi chủ thể đang nhìn đến.
  • Smile Value (nụ cười): Ước tính mức độ của nụ cười.
  • Face orientation (hướng khuôn mặt): Theo dõi ngáp, cao độ và cuộn đầu.

Nhận dạng khuôn mặt như tên gọi sẽ cung cấp khả năng nhận dạng mọi người trong ảnh. Điều đáng chú ý là tất cả quá trình xử lý được thực hiện nội bộ không giống như cloud.

Các tính năng này có thể được sử dụng thời gian thực (video/camera) hoặc offline (gallery). Trong bài tập của chúng tôi, chúng tôi sẽ sử dụng các tính năng offline, nhưng có sự khác biệt rất nhỏ giữa hai cách tiếp cận.

Tham khảo tài liệu trực tuyến cho các thiết bị được hỗ trợ để tìm hiểu thêm về xử lý khuôn mặtnhận diện khuôn mặt.

5. Bổ sung nhận dạng và xử lý khuôn mặt

Trong phần này, chúng tôi sẽ đưa vào các phương thức hook vài dòng code để cung cấp cho ứng dụng của chúng tôi khả năng trích xuất các thuộc tính khuôn mặt và nhận diện con người. Hãy tải xuống mã nguồn từ GitHub và mở dự án trong Android Studio. Ngoài ra, bạn có thể tải về dự án đã hoàn thành.

Bước 1: Cài đặt Snapdragon SDK

Điều đầu tiên chúng ta cần làm là lấy SDK từ website của Qualcomm. Lưu ý rằng bạn sẽ cần phải đăng ký (hoặc đăng nhập) và đồng ý với các điều khoản và điều kiện của Qualcomm.

Sau khi tải xuống, giải nén và điều hướng đến /Snapdragon_sdk_2.3.1/java/libs/libs_facial_ Processing/. Sao chép file sd-sdk-face-process.jar vào thư mục /app/libs/ của bạn như hiển thị bên dưới.

Android Studio Libs folder via the Project File panel

Sau khi sao chép Snapdragon SDK, nhấp chuột phải vào sd-sdk-face-process.jar và chọn Add as Library... từ danh sách các tùy chọn.

Android Studio File menu - Add As Library option

Điều này sẽ thêm thư viện dưới dạng phần phụ thuộc trong file build.gradle của bạn như hiển thị bên dưới.

Bước cuối cùng là bổ sung thư viện riêng. Để thực hiện việc này, hãy tạo một thư mục có tên jniLibs trong thư mục /app/src/main/ của bạn và sao chép thư mục armeabi (từ SDK tải xuống) và nội dung của nó vào thư mục đó.

Android Studios Project folder view showing the structure where to put the native binaries

Bây giờ chúng tôi đã sẵn sàng triển khai logic để định danh mọi người bằng chức năng của API. Các đoạn code sau nằm trong class GalleryScanner.

Bước 2: Khởi tạo

Trước tiên chúng ta hãy xử lý phương thức hook khởi tạo.

Trước tiên chúng ta cần kiểm tra xem liệu thiết bị có hỗ trợ xử lý khuôn mặt và nhận dạng khuôn mặt. Nếu không, chúng ta sẽ cho ra một exceptionUnsupportedOperationException.

Sau đó, chúng tôi gán tham chiếu cục bộ của chúng tôi về class FacialProcessing, mFacialProcessing, đến một giá trị bằng phương thức factory getInstance. Phương thức này sẽ trả về null nếu một đối tượng đã được sử dụng, trong trường hợp đó, người tiêu dùng được yêu cầu gọi release trên tham chiếu đó.

Nếu chúng tôi đã lấy thành công một giá trị của đối tượng FacialProcessing, chúng tôi sẽ định cấu hình nó bằng cách đặt độ tin cậy trước tiên. Chúng tôi thực hiện điều này bằng cách sử dụng một biến cục bộ, là 57 trong trường hợp này từ phạm vi từ 0 đến 100. Sự tự tin là một ngưỡng khi cố gắng giải quyết danh tính. Bất kỳ điều phù hợp nào dưới ngưỡng này sẽ được coi là danh tính riêng biệt.

Về mặt xác định giá trị, theo như tôi có thể nói, đây là quá trình thử và sai xót. Rõ ràng ngưỡng càng cao, sự nhận biết càng chính xác, với sự đánh đổi bằng cách tăng số lượng false-positive.

Sau đó, chúng tôi đặt chế độ FacialProcessing thành FP_MODE_STILL. Các tùy chọn của bạn ở đây là FP_MODE_STILL hoặc FP_MODE_VIDEO. Theo tên gọi, một chọn lựa được tối ưu hóa cho hình ảnh tĩnh trong khi chọn lựa còn lại dành các khung hình liên tiếp, cả hai đều có trường hợp sử dụng rõ ràng.

P_MODE_STILL như bạn có thể nghi ngờ và cung cấp kết quả chính xác hơn. Nhưng như bạn sẽ thấy sau này, FP_MODE_STILL được ngụ ý bởi phương thức chúng tôi sử dụng để xử lý hình ảnh để dòng này có thể được bỏ qua. Tôi chỉ bổ sung cho đầy đủ.

Sau đó, chúng tôi gọi loadAlbum (phương thức của class GalleryScanner), đây là điều chúng ta sẽ xem xét tiếp theo.

Dòng thú vị duy nhất ở đây là:

Phương pháp đối lập của nó là:

Một giá trị FacialProcessing có thể được coi là một session. Những người được bổ sung vào (được giải thích bên dưới) được lưu trữ cục bộ (gọi là "album nhận dạng") trong trường hợp đó. Để cho phép album của bạn duy trì qua nhiều session, nghĩa là, mỗi lần bạn có được một giá trị mới, bạn cần một cách để duy trì và tải chúng.

Phương thức serializeRecogntionAlbum chuyển đổi album thành một mảng byte và ngược lại, deserializeRecognitionAlbum sẽ tải và phân tích một album được lưu trữ trước đó dưới dạng một mảng byte.

Bước 3: Hủy khởi tạo

Bây giờ chúng ta biết cách khởi tạo class FacialProcessing để xử lý và nhận dạng khuôn mặt. Bây giờ chúng ta hãy tập trung vào việc khởi tạo lại nó bằng cách thực hiện phương thức deinitFacialProcessing.

Như đã đề cập ở trên, chỉ có thể có một phiên bản của class FacialProcessing tại một thời điểm vì vậy chúng tôi cần đảm bảo chúng tôi phát hành nó trước khi hoàn thành nhiệm vụ của mình. Chúng tôi làm điều này thông qua phương pháp thức release. Nhưng trước tiên, chúng tôi làm cho album nhận dạng tiếp tục tồn tại để chúng tôi có thể sử dụng kết quả qua nhiều session. Trong trường hợp này, khi người dùng chụp hoặc nhận ảnh mới, chúng tôi muốn đảm bảo rằng chúng tôi sử dụng các danh tính được nhận dạng trước đó cho cùng một người.

Bước 4: Xử lý hình ảnh

Cuối cùng chúng ta cũng sẵn sàng đưa ra phương thức hook final và sử dụng class FacialProcessing. Các code sau nằm trong phương thức processImage. Tôi đã chia chúng ra cho rõ ràng.

Phương thức này tham chiếu đến một giá trị của class ContentValues, nó lưu giữ metadata cho hình ảnh này, cùng với URI trỏ đến hình ảnh. Chúng tôi sử dụng tham chiếu này để tải hình ảnh vào bộ nhớ.

Đoạn code sau đây dùng thay thế comment phía trên //continued below (1).

Như đã đề cập ở trên, trước tiên chúng ta chuyển hình ảnh tĩnh sang đối tượng FacialProcessing thông qua phương thức setBitmap. Việc dùng phương thức này hoàn toàn sử dụng chế độ FP_MODE_STILL. Phương thức này trả về True nếu hình ảnh được xử lý thành công và False nếu quá trình xử lý thất bại.

Phương pháp thay thế để xử lý hình ảnh phát trực tuyến (thường cho các khung xem trước của máy ảnh) là:

Hầu hết các tham số đều rõ ràng. Bạn phải xem liệu khung hình có bị lật hay không (điều này thường là cần thiết cho máy ảnh mặt trước) và nếu có bất kỳ độ xoay nào được áp dụng (thường được đặt thông qua phương thức setDisplayOrientation của một đối tượng Camera).

Sau đó chúng tôi truy vấn số lượng khuôn mặt được phát hiện và chỉ tiếp tục nếu tìm thấy ít nhất một khuôn mặt. Phương thức getFaceData trả về các chi tiết cho từng khuôn mặt được phát hiện dưới dạng một mảng các đối tượng FaceData, trong đó mỗi đối tượng FaceData đóng gói các đặc điểm khuôn mặt bao gồm:

  • ranh giới khuôn mặt (FACE_RECT)
  • vị trí mặt, miệng và mắt (FACE_COORDINATES)
  • đường viền của khuôn mặt (FACE_CONTOUR)
  • mức độ của nụ cười (FACE_SMILE)
  • hướng của đôi mắt (FACE_GAZE)
  • cờ cho biết nếu một trong hai mắt (hoặc cả hai mắt) đang nhấp nháy (FACE_BLINK)
  • độ nghiêng, mức độ và lăn mặt (FACE_ORIENTATION)
  • nhận dạng được tạo ra hoặc dẫn xuất (FACE_IDENTIFICATION)

Phương thức này là một kiểu overload; trong đó có một tập hợp các enum (như được mô tả ở trên) cho các điểm đặc trưng được đưa vào, loại bỏ/giảm thiểu các phép tính rườm rà.

Bây giờ chúng tôi chuyển sang kiểm tra đối tượng FaceData để trích xuất danh tính và tính năng. Trước tiên chúng ta hãy xem cách nhận dạng khuôn mặt được thực hiện.

Đoạn code sau đây là để thay thế comment bên trên // continued below (2).

Trước tiên chúng tôi yêu cầu id người được chỉ định thông qua phương thức getPersonId. Phương thức này sẽ trả về -111 (FP_PERSON_NOT_REGISTERED) nếu không có danh tính trong album hiện đang được tải, nếu không sẽ trả lại id của một người phù hợp từ album đã tải.

Nếu không có danh tính tồn tại, thì chúng tôi sẽ bổ sung nó thông qua phương thức addPerson của đối tượng FacialProcessing, chuyển cho nó chỉ mục của mục FaceData mà chúng tôi hiện đang kiểm tra. Phương thức trả về id người được chỉ định nếu thành công, nếu không sẽ trả về một lỗi. Điều này xảy ra khi cố gắng bổ sung một danh tính đã tồn tại.

Ngoài ra, khi người đó được khớp với một danh tính được lưu trữ trong album đã tải của chúng tôi, chúng tôi gọi phương thức updatePerson của đối tượng FacialProcessing, truyền cho nó id và chỉ mục hiện có của mục FaceData. Thêm một người nhiều lần làm tăng hiệu suất của nhận biết. Bạn có thể bổ sung tối đa 10 khuôn mặt cho một người.

Dòng cuối cùng chỉ trả về id nhận dạng được liên kết từ database của chúng tôi, chèn nó vào nếu id người không tồn tại.

Nó không được hiển thị ở trên, nhưng đối tượng FaceData hiển thị phương thức getRecognitionConfidence để trả về độ tin cậy của nhận dạng (0 đến 100). Tùy thuộc vào nhu cầu của bạn, bạn có thể sử dụng điều này để ảnh hưởng đến dòng chảy.

Đoạn code cuối cùng trình bày cách truy vấn từng tính năng khác từ phiên bản FaceData. Trong bản demo này, chúng tôi không sử dụng chúng, nhưng với một chút trí tưởng tượng, tôi chắc chắn bạn có thể nghĩ ra cách tốt để sử dụng chúng.

Đoạn code sau đây là để thay thế comment bên trên // continued below (3).

Việc đó hoàn thành code xử lý. Nếu bạn quay lại thư viện và chạm vào một hình ảnh, bạn sẽ thấy nó lọc ra bất kỳ ảnh nào không chứa bất kỳ người nào được xác định trong ảnh đã chọn.

Tổng kết

Chúng tôi đã bắt đầu hướng dẫn này bằng cách nói về cách công nghệ có thể được sử dụng để giúp tổ chức nội dung của người dùng. Trong điện toán nhận thức ngữ cảnh, mục tiêu của nó là sử dụng bối cảnh như một gợi ý ngầm để làm phong phú thêm sự tương tác nghèo nàn từ con người với máy tính, giúp tương tác với máy tính dễ dàng hơn, điều này được gọi là auto-tagging (tự động gắn thẻ). Bằng cách đánh dấu nội dung với dữ liệu có ý nghĩa và hữu ích hơn cho cả máy tính và chúng tôi, chúng tôi cho phép lọc và xử lý thông minh hơn.

Chúng tôi đã thấy nó được sử dụng thường xuyên với nội dung văn bản, ví dụ rõ ràng nhất là các bộ lọc spam và gần đây hơn là các trình đọc tin tức, nhưng không nhiều với nội dung đa phương tiện, chẳng hạn như hình ảnh, nhạc và video. Các công cụ như Snapdragon SDK cung cấp cho chúng tôi cơ hội trích xuất các tính năng hữu ích từ đa phương tiện, hiển thị các thuộc tính của nó cho người dùng và máy tính.

Không khó để tưởng tượng làm thế nào bạn có thể mở rộng ứng dụng của chúng tôi để cho phép lọc dựa trên cảm xúc bằng cách sử dụng nụ cười làm tính năng chính hoặc hoạt động xã hội bằng cách đếm số lượng khuôn mặt. Một triển khai như vậy có thể được nhìn thấy trong tính năng Smart Gallery.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.