Phần phụ trợ Tìm kiếm sản phẩm API Call Vision trên Android

1. Trước khi bắt đầu

bd8c01b2f8013c6d.png

Bạn đã xem bản minh họa Google Ống kính, nơi bạn có thể hướng máy ảnh điện thoại của mình vào một vật và tìm nơi bạn có thể mua máy ảnh trên mạng chưa? Nếu bạn muốn tìm hiểu cách thêm tính năng tương tự vào ứng dụng của mình, thì lớp học mã này là dành cho bạn. Đây là một phần của lộ trình học tập hướng dẫn bạn cách xây dựng tính năng tìm kiếm hình ảnh sản phẩm vào ứng dụng dành cho thiết bị di động.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách gọi một phần phụ trợ được xây dựng bằng Tìm kiếm sản phẩm API Vision từ một ứng dụng dành cho thiết bị di động. Phụ trợ này có thể lấy hình ảnh truy vấn và tìm kiếm các sản phẩm tương tự trực quan từ một danh mục sản phẩm.

Bạn có thể tìm hiểu về các bước còn lại để xây dựng tính năng tìm kiếm sản phẩm trực quan, bao gồm cả cách sử dụng tính năng Phát hiện và theo dõi đối tượng bộ công cụ máy học để phát hiện các đối tượng trong hình ảnh truy vấn và cho phép người dùng chọn sản phẩm họ muốn tìm kiếm, trong đường dẫn học tập.

Sản phẩm bạn sẽ tạo ra

  • Trong lớp học lập trình này, bạn bắt đầu với ứng dụng Android. Ứng dụng này có thể phát hiện đối tượng từ hình ảnh nhập vào. Bạn sẽ viết mã để lấy đối tượng mà người dùng chọn, gửi đến đối tượng phụ trợ tìm kiếm sản phẩm và hiển thị kết quả tìm kiếm trên màn hình.
  • Cuối cùng, bạn sẽ thấy một nội dung tương tự như hình ảnh ở bên phải.

Kiến thức bạn sẽ học được

  • Cách gọi và phân tích cú pháp nội dung phản hồi của API Tìm kiếm sản phẩm API Vision từ ứng dụng Android

Bạn cần có

  • Phiên bản Android Studio phiên bản 4.1.2 trở lên gần đây
  • Trình mô phỏng Android Studio hoặc thiết bị Android thực
  • Mã mẫu
  • Kiến thức cơ bản về việc phát triển Android trong Kotlin

Lớp học lập trình này tập trung vào Tìm kiếm sản phẩm API Vision. Các khái niệm và khối mã không liên quan sẽ không được khám phá và cung cấp để bạn chỉ cần sao chép và dán.

2. Giới thiệu về Tìm kiếm sản phẩm API Vision

Tìm kiếm sản phẩm API Vision là một tính năng trong Google Cloud cho phép người dùng tìm kiếm các sản phẩm tương tự trực quan từ một danh mục sản phẩm. Nhà bán lẻ có thể tạo sản phẩm, mỗi sản phẩm chứa những hình ảnh tham khảo mô tả trực quan sản phẩm từ một góc nhìn. Sau đó, bạn có thể thêm các sản phẩm này vào bộ sản phẩm (tức là danh mục sản phẩm). Hiện tại, Tìm kiếm sản phẩm API Vision hỗ trợ những danh mục sản phẩm sau đây: đồ gia dụng, hàng may mặc, đồ chơi, hàng đóng gói và hàng hóa nói chung.

Khi người dùng truy vấn bộ sản phẩm bằng hình ảnh của riêng họ, Tìm kiếm sản phẩm API Vision sẽ áp dụng công nghệ máy học để so sánh sản phẩm trong hình ảnh truy vấn của người dùng với các hình ảnh trong bộ sản phẩm của nhà bán lẻ, sau đó trả về danh sách xếp hạng các kết quả tương tự về mặt hình ảnh và ngữ nghĩa.

3. Tải và chạy ứng dụng khởi động

Tải mã nguồn xuống

Nhấp vào đường liên kết sau đây để tải toàn bộ mã nguồn cho lớp học lập trình này:

Giải nén tệp zip đã tải xuống. Thao tác này sẽ giải nén thư mục gốc (odml-pathways-main) chứa tất cả tài nguyên mà bạn cần. Đối với lớp học lập trình này, bạn sẽ chỉ cần các nguồn trong thư mục con product-search/codelab2/android.

Thư mục con codelab2 trong kho lưu trữ odml-pathways chứa hai thư mục:

  • android_studio_folder.pngbắt đầu – Bắt đầu bằng mã mà bạn xây dựng dựa trên lớp học lập trình này.
  • android_studio_folder.pngfinal – Mã hoàn tất cho ứng dụng mẫu đã hoàn tất.

Ứng dụng dành cho người mới bắt đầu ở đây là ứng dụng mà bạn đã xây dựng trong phần Phát hiện đối tượng trong hình ảnh để xây dựng tính năng tìm kiếm sản phẩm trực quan: Android. Ứng dụng này dùng tính năng Phát hiện và theo dõi đối tượng của Bộ công cụ máy học (ML) để phát hiện các đối tượng từ một hình ảnh và hiển thị các đối tượng đó trên màn hình.

Nhập ứng dụng vào Android Studio

Bắt đầu bằng cách nhập ứng dụng bắt đầu vào Android Studio.

Chuyển đến Android Studio, chọn Nhập dự án (Gradle, Eclipse ADT, v.v.) và chọn thư mục starter từ mã nguồn mà bạn đã tải xuống trước đó.

7c0f27882a2698ac.png

Chạy ứng dụng dành cho người mới bắt đầu

Sau khi nhập dự án vào Android Studio, bạn có thể chạy ứng dụng lần đầu tiên. Kết nối thiết bị Android của bạn qua USB với máy chủ lưu trữ hoặc Bắt đầu trình mô phỏng Android Studio,rồi nhấp vào Chạy ( tức thì.png) trên thanh công cụ Android Studio.

(Nếu nút này bị tắt, hãy nhớ chỉ nhập điều kiện khởi động/ứng dụng/build.gradle, chứ không phải toàn bộ kho lưu trữ.)

Bây giờ, ứng dụng đã chạy trên thiết bị Android của bạn. Tính năng này đã có tính năng phát hiện đối tượng: phát hiện các mục thời trang từ hình ảnh và cho bạn biết vị trí của các đối tượng đó. Hãy thử với các ảnh đã đặt trước để xác nhận.

c6102a808fdfcb11.png

Ảnh chụp màn hình của ứng dụng khởi động có thể phát hiện vật thể trong hình ảnh

Tiếp theo, bạn sẽ mở rộng ứng dụng để gửi các đối tượng đã phát hiện đến phần phụ trợ Tìm kiếm sản phẩm API Vision và hiển thị kết quả tìm kiếm trên màn hình.

4. Xử lý lựa chọn đối tượng

Cho phép người dùng nhấn vào một đối tượng đã phát hiện để chọn

Bây giờ bạn sẽ thêm mã để cho phép người dùng chọn một đối tượng từ hình ảnh và bắt đầu tìm kiếm sản phẩm. Ứng dụng khởi động đã có khả năng phát hiện các vật thể trong hình ảnh đó. Có thể có nhiều đối tượng trong hình ảnh, hoặc đối tượng được phát hiện chỉ chiếm một phần nhỏ của hình ảnh. Do đó, bạn cần yêu cầu người dùng nhấn vào một trong các đối tượng đã phát hiện để cho biết đối tượng mà họ muốn sử dụng để tìm kiếm sản phẩm.

9cdfcead6d95a87.png

Ảnh chụp màn hình về những mặt hàng thời trang được phát hiện trong hình ảnh

Để đảm bảo lớp học lập trình đơn giản và tập trung vào công nghệ máy học, chúng tôi đã triển khai một số mã Android mẫu nguyên mẫu trong ứng dụng dành cho người mới bắt đầu để giúp bạn phát hiện đối tượng mà người dùng đã nhấn vào. Chế độ xem hiển thị hình ảnh trong hoạt động chính (ObjectDetectorActivity) thực ra là chế độ xem tùy chỉnh (ImageClickableView) mở rộng hệ điều hành Android mặc định ImageView. Triển khai một số phương thức tiện ích tiện lợi, bao gồm:

  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) Đây là lệnh gọi lại để nhận hình ảnh bị cắt chỉ chứa đối tượng mà người dùng đã nhấn vào. Bạn sẽ gửi hình ảnh đã cắt này đến phần phụ trợ tìm kiếm sản phẩm.

Thêm mã để xử lý việc người dùng nhấn vào các đối tượng đã phát hiện.

Chuyển đến phương thức initViews trong lớp ObjectDetectorActivity và thêm các dòng này vào cuối phương thức: (Android Studio sẽ thông báo cho bạn rằng không thể tìm thấy phương thức startProductImageSearch . Đừng lo, bạn sẽ triển khai hàm này một chút sau.)

// Callback received when the user taps on any of the detected objects.
ivPreview.setOnObjectClickListener { objectImage ->
    startProductImageSearch(objectImage)
}

onObjectClickListener được gọi bất cứ khi nào người dùng nhấn vào bất kỳ đối tượng được phát hiện nào trên màn hình. Hàm này nhận được hình ảnh đã cắt chỉ chứa đối tượng được chọn. Ví dụ: nếu người dùng nhấn vào người mặc chiếc váy đó ở bên phải, thì trình nghe sẽ được kích hoạt bằng tên objectImage ở bên dưới.

9cac8458d0f326e6.png

Ví dụ về hình ảnh đã cắt được chuyển đến onObjectClickListener

Gửi hình ảnh bị cắt đến hoạt động tìm kiếm sản phẩm

Bây giờ, bạn sẽ triển khai logic gửi hình ảnh truy vấn đến phần phụ trợ Tìm kiếm sản phẩm API Vision trong một hoạt động riêng biệt (ProductSearchActivity).

Tất cả các thành phần giao diện người dùng đều đã được triển khai trước nên bạn có thể tập trung vào việc viết mã để giao tiếp với phần phụ trợ tìm kiếm sản phẩm.

25939f5a13eeb3c3.png

Ảnh chụp màn hình các thành phần giao diện người dùng trên Hoạt động tìm kiếm sản phẩm

Thêm mã để gửi hình ảnh đối tượng mà người dùng đã chọn đến ProductSearchActivity.

Quay lại Android Studio và thêm phương thức startProductImageSearch này vào lớp ObjectDetectorActivity:

private fun startProductImageSearch(objectImage: Bitmap) {
    try {
        // Create file based Bitmap. We use PNG to preserve the image quality
        val savedFile = createImageFile(ProductSearchActivity.CROPPED_IMAGE_FILE_NAME)
        objectImage.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(savedFile))

        // Start the product search activity (using Vision Product Search API.).
        startActivity(
            Intent(
                    this,
                    ProductSearchActivity::class.java
            ).apply {
                // As the size limit of a bundle is 1MB, we need to save the bitmap to a file
                // and reload it in the other activity to support large query images.
                putExtra(
                    ProductSearchActivity.REQUEST_TARGET_IMAGE_PATH,
                    savedFile.absolutePath
                )
            })
    } catch (e: Exception) {
        // IO Exception, Out Of memory ....
        Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show()
        Log.e(TAG, "Error starting the product image search activity.", e)
    }
}

Đoạn mã thực hiện 3 thao tác:

  • Chụp ảnh bị cắt và chuyển đổi tuần tự hình ảnh thành tệp PNG.
  • Bắt đầu ProductSearchActivity để thực thi trình tự tìm kiếm sản phẩm.
  • Bao gồm URI hình ảnh đã cắt trong ý định hoạt động bắt đầu để ProductSearchActivity có thể truy xuất hình ảnh đó sau này để sử dụng làm hình ảnh truy vấn.

Có một vài điều cần lưu ý:

  • Logic để phát hiện các đối tượng và truy vấn phần phụ trợ đã được chia thành 2 hoạt động chỉ để giúp lớp học lập trình dễ hiểu hơn. Bạn có quyền quyết định cách triển khai chúng trong ứng dụng của mình.
  • Bạn cần ghi hình ảnh truy vấn vào một tệp và chuyển URI hình ảnh giữa các hoạt động vì hình ảnh truy vấn có thể lớn hơn giới hạn kích thước 1MB của một ý định Android.
  • Bạn có thể lưu trữ hình ảnh truy vấn ở định dạng PNG vì đó là định dạng không bị mất.

Truy xuất hình ảnh truy vấn trong hoạt động tìm kiếm sản phẩm

Trong ProductSearchActivity, mã để truy xuất hình ảnh truy vấn và hiển thị hình ảnh trên màn hình đã được triển khai trong ứng dụng dành cho người mới bắt đầu.

Chuyển đến phương thức onCreate và xác nhận mã này đã ở đó:

// Receive the query image and show it on the screen
intent.getStringExtra(REQUEST_TARGET_IMAGE_PATH)?.let { absolutePath ->
    viewBinding.ivQueryImage.setImageBitmap(BitmapFactory.decodeFile(absolutePath))
}

Chạy ứng dụng

Giờ hãy nhấp vào Chạy ( tức thì.png) trong thanh công cụ Android Studio.

Sau khi tải, hãy nhấn vào bất kỳ hình ảnh đặt trước nào rồi chọn một trong các đối tượng phát hiện được.

Xác nhận rằng ProductSearchActivity hiển thị cùng với hình ảnh mà bạn đã nhấn vào. Nút Tìm kiếm chưa làm gì nhưng chúng tôi sẽ triển khai nút này tiếp theo.

feed40f81b8b43801.png

Bạn sẽ thấy một màn hình tương tự sau khi nhấn vào một trong các đối tượng phát hiện được.

5. Khám phá phần phụ trợ tìm kiếm sản phẩm

Xây dựng phần phụ trợ tìm kiếm hình ảnh sản phẩm

Lớp học mã này yêu cầu phần phụ trợ tìm kiếm sản phẩm được xây dựng bằng tính năng Tìm kiếm sản phẩm API Vision. Có hai cách để thực hiện việc này:

Lựa chọn 1: Sử dụng phần phụ trợ minh họa đã được triển khai cho bạn

Bạn có thể tiếp tục tham gia lớp học lập trình này bằng cách sử dụng phần phụ trợ tìm kiếm sản phẩm mà Google đã triển khai cho bạn. Bạn có thể sao chép phần phụ trợ minh họa bằng cách làm theo hướng dẫn bắt đầu nhanh Tìm kiếm sản phẩm API Vision.

Tùy chọn 2: Tạo phần phụ trợ của riêng bạn bằng cách làm theo hướng dẫn bắt đầu nhanh về Tìm kiếm sản phẩm cho API Vision

Chúng tôi đề xuất tùy chọn này cho những người muốn tìm hiểu chi tiết về cách xây dựng phụ trợ tìm kiếm sản phẩm để bạn có thể xây dựng phụ trợ cho danh sách sản phẩm của riêng mình sau này. Bạn cần có:

  • Một tài khoản Google Cloud có bật tính năng thanh toán. (Đây có thể là tài khoản dùng thử miễn phí.)
  • Một số kiến thức về khái niệm của Google Cloud, bao gồm các dự án, tài khoản dịch vụ, v.v.

Bạn có thể tìm hiểu cách thực hiện việc này vào lúc khác trong lộ trình học tập.

Tìm hiểu các khái niệm quan trọng

Bạn sẽ gặp phải những khái niệm sau đây khi tương tác với phần phụ trợ tìm kiếm sản phẩm:

  • Bộ sản phẩm: Bộ sản phẩm là vùng chứa đơn giản cho một nhóm sản phẩm. Một danh mục sản phẩm có thể được trình bày dưới dạng một bộ sản phẩm và các sản phẩm của bộ sản phẩm đó.
  • Sản phẩm: Sau khi tạo một bộ sản phẩm, bạn có thể tạo và thêm các sản phẩm đó vào bộ sản phẩm.
  • Hình ảnh tham khảo của sản phẩm: Đây là những bức ảnh chứa nhiều góc nhìn về sản phẩm. Hình ảnh tham chiếu được dùng để tìm kiếm các sản phẩm tương tự nhau về mặt hình ảnh.
  • Tìm kiếm sản phẩm: Sau khi tạo bộ sản phẩm và lập chỉ mục nhóm sản phẩm, bạn có thể truy vấn nhóm sản phẩm bằng API Cloud Vision.

Tìm hiểu về danh mục sản phẩm đặt sẵn

Phần phụ trợ tìm kiếm sản phẩm được sử dụng trong lớp học lập trình này được tạo bằng cách sử dụng API Tìm kiếm sản phẩm Vision API và một danh mục sản phẩm gồm khoảng 100 chiếc giày và hình ảnh váy. Dưới đây là một số hình ảnh từ danh mục:

4f1a8507b74ab178.png 79a5fc6c829eca77.png 3528c872f813826e.png

Ví dụ từ danh mục sản phẩm đặt trước

Gọi phần phụ trợ minh họa tính năng tìm kiếm sản phẩm

Bạn có thể gọi Tìm kiếm sản phẩm API Vision trực tiếp từ một ứng dụng dành cho thiết bị di động bằng cách thiết lập khóa Google Cloud API và hạn chế quyền truy cập vào khóa API chỉ với ứng dụng của bạn.

Để giữ cho lớp học lập trình này đơn giản, chúng tôi đã thiết lập một điểm cuối proxy cho phép bạn truy cập vào phần phụ trợ minh họa mà không phải lo lắng về khóa API và tính năng xác thực. Tệp này nhận yêu cầu HTTP từ ứng dụng dành cho thiết bị di động, thêm khóa API và chuyển tiếp yêu cầu đến phần phụ trợ Tìm kiếm sản phẩm API Vision. Sau đó, proxy sẽ nhận phản hồi của phần phụ trợ và trả về ứng dụng dành cho thiết bị di động.

Trong lớp học lập trình này, bạn sẽ sử dụng hai API của Tìm kiếm sản phẩm API Vision:

  • projects.locations.images.annotate: Gửi hình ảnh truy vấn đến máy chủ và nhận danh sách các sản phẩm từ một danh mục sản phẩm được thiết lập sẵn tương tự trực quan với hình ảnh truy vấn.
  • projects.locations.products.referenceImages.get: Lấy URI của hình ảnh sản phẩm được trả về trong lệnh gọi API ở trên để hiển thị cho người dùng.

6. Triển khai ứng dụng API

Hiểu quy trình tìm kiếm sản phẩm

Thực hiện theo quy trình công việc này để tiến hành tìm kiếm sản phẩm với phần phụ trợ:

Triển khai lớp ứng dụng API

Bây giờ, bạn sẽ triển khai mã để gọi phần phụ trợ tìm kiếm sản phẩm trong một lớp riêng có tên là ProductSearchAPIClient. Chúng tôi đã triển khai một số mã nguyên mẫu cho bạn trong ứng dụng dành cho người mới bắt đầu:

  • class ProductSearchAPIClient: Lớp này hiện không có nội dung, nhưng có một số phương pháp mà bạn sẽ triển khai sau trong lớp học lập trình này.
  • fun convertBitmapToBase64(bitmap: Bitmap): Chuyển đổi bản sao Bitmap thành bản trình bày base64 để gửi đến phần phụ trợ tìm kiếm sản phẩm
  • fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>>: Gọi API projects.locations.images.annotate và phân tích cú pháp nội dung phản hồi.
  • fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult>: Gọi API projects.locations.products.referenceImages.get rồi phân tích cú pháp nội dung phản hồi.
  • SearchResult.kt: Tệp này chứa một số lớp dữ liệu để đại diện cho các loại do phần phụ trợ Tìm kiếm sản phẩm API Vision trả về.

Chỉ định cấu hình API

Chuyển đến lớp ProductSearchAPIClient và bạn sẽ thấy một số cấu hình của phần phụ trợ tìm kiếm sản phẩm đã được xác định:

// Define the product search backend
// Option 1: Use the demo project that we have already deployed for you
const val VISION_API_URL =
    "https://us-central1-odml-codelabs.cloudfunctions.net/productSearch"
const val VISION_API_KEY = ""
const val VISION_API_PROJECT_ID = "odml-codelabs"
const val VISION_API_LOCATION_ID = "us-east1"
const val VISION_API_PRODUCT_SET_ID = "product_set0"
  • VISION_API_URL là điểm cuối API của Cloud Vision API. Khi bạn thực hiện phần phụ trợ minh họa, hãy đặt phần này thành điểm cuối proxy. Tuy nhiên, nếu triển khai phần phụ trợ của riêng mình, bạn sẽ cần thay đổi phần này thành điểm cuối API Cloud Vision. https://vision.googleapis.com/v1.
  • VISION_API_KEY là khóa API của Dự án Cloud của bạn. Vì proxy đã xử lý việc xác thực, bạn có thể để trống trường này.
  • VISION_API_PROJECT_ID là mã dự án trên Cloud. odml-codelabs là dự án Cloud triển khai phần phụ trợ minh họa.
  • VISION_API_LOCATION_ID là vị trí trên đám mây, nơi triển khai phụ trợ tìm kiếm sản phẩm. us-east1 là nơi chúng tôi đã triển khai phụ trợ minh họa.
  • VISION_API_PRODUCT_SET_ID là mã của danh mục sản phẩm (còn gọi là "product set" trong cụm từ API Vision) mà bạn muốn tìm kiếm sản phẩm tương tự bằng hình ảnh. Bạn có thể có nhiều danh mục trong một dự án Cloud. product_set0 là danh mục sản phẩm được thiết lập sẵn của phần phụ trợ minh họa.

7. Gọi API tìm kiếm sản phẩm

Khám phá yêu cầu và định dạng phản hồi của API

Bạn có thể tìm các sản phẩm tương tự bằng một hình ảnh nhất định bằng cách chuyển URI Google Cloud Storage của URL hình ảnh, URL web hoặc chuỗi được mã hóa base64 của hình ảnh tới Tìm kiếm sản phẩm API Vision. Trong lớp học lập trình này, bạn sẽ sử dụng tùy chọn chuỗi được mã hóa base64 vì hình ảnh truy vấn của chúng tôi chỉ tồn tại trong thiết bị của người dùng.

Bạn cần gửi yêu cầu POST đến điểm cuối projects.locations.images.annotate với nội dung JSON yêu cầu này:

{
  "requests": [
    {
      "image": {
        "content": {base64-encoded-image}
      },
      "features": [
        {
          "type": "PRODUCT_SEARCH",
          "maxResults": 5
        }
      ],
      "imageContext": {
        "productSearchParams": {
          "productSet": "projects/{project-id}/locations/{location-id}/productSets/{product-set-id}",
          "productCategories": [
               "apparel-v2"
          ],
        }
      }
    }
  ]
}

Có một số thông số cần được chỉ định:

  • mã hóa hình ảnh base64: Biểu diễn Base64 (chuỗi ASCII) của dữ liệu tệp nhị phân của hình ảnh truy vấn.
  • project-id: Mã dự án GCP của bạn.
  • location-id: Giá trị nhận dạng vị trí hợp lệ.
  • product-set-id: Mã của bộ sản phẩm mà bạn muốn chạy thao tác.

Vì danh mục sản phẩm của bạn chỉ chứa giày và hình ảnh váy, nên hãy chỉ định Danh mục sản phẩmapparel-v2. v2 ở đây có nghĩa là chúng tôi sử dụng phiên bản 2 của mô hình máy học tìm kiếm sản phẩm may mặc.

Nếu yêu cầu thành công, máy chủ trả về mã trạng thái HTTP 200 OK và phản hồi ở định dạng JSON. JSON phản hồi bao gồm hai loại kết quả sau:

  • productSearchKết quả - Chứa danh sách các sản phẩm phù hợp cho toàn bộ hình ảnh.
  • ProductGroupedResults – Chứa các tọa độ hộp giới hạn và các mục phù hợp cho từng sản phẩm được xác định trong hình ảnh.

Vì sản phẩm này đã bị cắt khỏi hình ảnh gốc, nên bạn sẽ phân tích cú pháp các kết quả trong danh sách productSearchResult.

Dưới đây là một số trường quan trọng trong đối tượng kết quả tìm kiếm sản phẩm:

  • product.name: Giá trị nhận dạng duy nhất của sản phẩm ở định dạng projects/{project-id}/locations/{location-id}/products/{product_id}
  • product.score: Một giá trị cho biết mức độ tương tự của kết quả tìm kiếm so với hình ảnh truy vấn. Giá trị càng cao thì càng giống nhau.
  • product.image: Giá trị nhận dạng duy nhất của hình ảnh tham chiếu của sản phẩm ở định dạng projects/{project-id}/locations/{location-id}/products/{product_id}/referenceImages/{image_id}. Bạn sẽ cần gửi một yêu cầu API khác đến projects.locations.products.referenceImages.get để lấy URL của hình ảnh tham chiếu này để hình ảnh hiển thị trên màn hình.
  • product.labels [nhãn_sản_phẩm]: Danh sách các thẻ được xác định trước của sản phẩm. Điều này rất hữu ích nếu bạn muốn lọc các kết quả tìm kiếm để chỉ hiển thị một danh mục quần áo, chẳng hạn như váy.

Chuyển đổi hình ảnh truy vấn thành base64

Bạn cần phải chuyển đổi hình ảnh truy vấn thành dạng biểu diễn chuỗi base64 và đính kèm chuỗi vào đối tượng JSON trong nội dung yêu cầu.

Chuyển đến lớp ProductSearchAPIClient, tìm phương thức convertBitmapToBase64 trống và thay thế bằng phương thức triển khai này:

private fun convertBitmapToBase64(bitmap: Bitmap): String {
    val byteArrayOutputStream = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
    val byteArray: ByteArray = byteArrayOutputStream.toByteArray()
    return Base64.encodeToString(byteArray, Base64.DEFAULT)
}

Triển khai lệnh gọi API

Tiếp theo, tạo yêu cầu API tìm kiếm sản phẩm và gửi yêu cầu đó đến phần phụ trợ. Bạn sẽ sử dụng Volley để thực hiện yêu cầu API và trả lại kết quả bằng cách sử dụng API tác vụ.

Quay lại lớp ProductSearchAPIClient, tìm phương thức annotateImage trống và thay thế bằng phương thức triển khai này:

fun annotateImage(image: Bitmap): Task<List<ProductSearchResult>> {
    // Initialization to use the Task API
    val apiSource = TaskCompletionSource<List<ProductSearchResult>>()
    val apiTask = apiSource.task

    // Convert the query image to its Base64 representation to call the Product Search API.
    val base64: String = convertBitmapToBase64(image)

    // Craft the request body JSON.
    val requestJson = """
        {
          "requests": [
            {
              "image": {
                "content": """".trimIndent() + base64 + """"
              },
              "features": [
                {
                  "type": "PRODUCT_SEARCH",
                  "maxResults": $VISION_API_PRODUCT_MAX_RESULT
                }
              ],
              "imageContext": {
                "productSearchParams": {
                  "productSet": "projects/${VISION_API_PROJECT_ID}/locations/${VISION_API_LOCATION_ID}/productSets/${VISION_API_PRODUCT_SET_ID}",
                  "productCategories": [
                       "apparel-v2"
                     ]
                }
              }
            }
          ]
        }
    """.trimIndent()

    // Add a new request to the queue
    requestQueue.add(object :
        JsonObjectRequest(
            Method.POST,
            "$VISION_API_URL/images:annotate?key=$VISION_API_KEY",
            JSONObject(requestJson),
            { response ->
                // Parse the API JSON response to a list of ProductSearchResult object/
                val productList = apiResponseToObject(response)

                // Return the list.
                apiSource.setResult(productList)
            },
            // Return the error
            { error -> apiSource.setException(error) }
        ) {
        override fun getBodyContentType() = "application/json"
    }.apply {
        setShouldCache(false)
    })

    return apiTask
}

Hiển thị kết quả tìm kiếm trên giao diện người dùng

Giờ đây, mã API trong ProductSearchAPIClient đã sẵn sàng. Quay lại hoạt động ProductSearchActivity để triển khai mã giao diện người dùng.

Hoạt động đã có một số mã nguyên mẫu kích hoạt phương thức searchByImage(queryImage: Bitmap). Thêm mã để gọi phần phụ trợ và hiển thị kết quả trên giao diện người dùng vào phương thức hiện đang trống này.

apiClient.annotateImage(queryImage)
    .addOnSuccessListener { showSearchResult(it) }
    .addOnFailureListener { error ->
        Log.e(TAG, "Error calling Vision API Product Search.", error)
        showErrorResponse(error.localizedMessage)
    }

Phương thức showSearchResult chứa một số mã nguyên mẫu để phân tích cú pháp phản hồi API và hiển thị các thông tin này trên màn hình cho bạn.

Chạy chiến dịch

Giờ hãy nhấp vào Chạy ( tức thì.png) trong thanh công cụ Android Studio. Sau khi ứng dụng tải, hãy nhấn vào bất kỳ hình ảnh đặt trước nào, chọn một đối tượng được phát hiện, nhấn vào nút Tìm kiếm và xem kết quả tìm kiếm được trả về từ phần phụ trợ. Bạn sẽ thấy nội dung như sau:

bb5e7c27c283a2fe.png

Ảnh chụp màn hình kết quả tìm kiếm sản phẩm

Phần phụ trợ này đã trả về một danh sách các sản phẩm có hình ảnh tương tự nhau từ danh mục sản phẩm được thiết lập sẵn. Tuy nhiên, bạn có thể thấy rằng hình ảnh sản phẩm vẫn trống. Đó là vì điểm cuối projects.locations.images.annotate chỉ trả về các mã hình ảnh sản phẩm như projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77. Bạn cần thực hiện một lệnh gọi API khác đến điểm cuối projects.locations.products.referenceImage.get và lấy URL của hình ảnh tham chiếu này để hiển thị trên màn hình.

8. Lấy ảnh tham chiếu sản phẩm

Khám phá yêu cầu và định dạng phản hồi của API

Bạn sẽ gửi một yêu cầu HTTP GET với nội dung yêu cầu trống đến điểm cuối projects.locations.products.referenceImages.get để lấy URI của hình ảnh sản phẩm do điểm cuối tìm kiếm sản phẩm trả về.

Yêu cầu HTTP có dạng như sau:

GET $VISION_API_URL/projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77?key=$VISION_API_KEY

Nếu yêu cầu thành công, máy chủ trả về mã trạng thái HTTP 200 OK và phản hồi ở định dạng JSON như sau:

{
  "name":"projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77",
  "uri":"gs://cloud-ai-vision-data/product-search-tutorial/images/46991e7370ba11e8a1bbd20059124800.jpg"
}
  • name [tên]: Giá trị nhận dạng hình ảnh tham chiếu
  • uri: URI của hình ảnh trên Google Cloud Storage (GCS).

Hình ảnh tham chiếu của phần phụ trợ tìm kiếm sản phẩm minh họa được thiết lập để có quyền đọc công khai. Do đó, bạn có thể dễ dàng chuyển đổi URI GCS thành URL HTTP và hiển thị URL này trên giao diện người dùng của ứng dụng. Bạn chỉ cần thay thế tiền tố gs:// bằng https://storage.googleapis.com/.

Triển khai lệnh gọi API

Tiếp theo, tạo yêu cầu API tìm kiếm sản phẩm và gửi yêu cầu đó đến phần phụ trợ. Bạn sẽ sử dụng Volley và API tác vụ tương tự như lệnh gọi API tìm kiếm sản phẩm.

Quay lại lớp ProductSearchAPIClient, tìm phương thức fetchReferenceImage trống và thay thế bằng phương thức triển khai này:

private fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult> {
    // Initialization to use the Task API
    val apiSource = TaskCompletionSource<ProductSearchResult>()
    val apiTask = apiSource.task

    // Craft the API request to get details about the reference image of the product
    val stringRequest = object : StringRequest(
        Method.GET,
        "$VISION_API_URL/${searchResult.imageId}?key=$VISION_API_KEY",
        { response ->
            val responseJson = JSONObject(response)
            val gcsUri = responseJson.getString("uri")

            // Convert the GCS URL to its HTTPS representation
            val httpUri = gcsUri.replace("gs://", "https://storage.googleapis.com/")

            // Save the HTTPS URL to the search result object
            searchResult.imageUri = httpUri

            // Invoke the listener to continue with processing the API response (eg. show on UI)
            apiSource.setResult(searchResult)
        },
        { error -> apiSource.setException(error) }
    ) {

        override fun getBodyContentType(): String {
            return "application/json; charset=utf-8"
        }
    }
    Log.d(ProductSearchActivity.TAG, "Sending API request.")

    // Add the request to the RequestQueue.
    requestQueue.add(stringRequest)

    return apiTask
}

Phương thức này nhận đối tượng searchResult: ProductSearchResult do điểm cuối tìm kiếm sản phẩm trả về, sau đó làm theo các bước sau:

  1. Gọi điểm cuối của hình ảnh tham chiếu để lấy URI GCS của hình ảnh tham chiếu.
  2. Chuyển đổi URI GCS thành URL HTTP.
  3. Cập nhật thuộc tính httpUri của đối tượng searchResult bằng URL HTTP này.

Kết nối hai yêu cầu API

Quay lại annotateImage và sửa đổi để có được tất cả hình ảnh tham chiếu\39; URL HTTP trước khi trả về danh sách ProductSearchResult cho người gọi.

Tìm dòng này:

// Return the list.
apiSource.setResult(productList)

Sau đó, thay thế bằng triển khai này:

// Loop through the product list and create tasks to load reference images.
// We will call the projects.locations.products.referenceImages.get endpoint
// for each product.
val fetchReferenceImageTasks = productList.map { fetchReferenceImage(it) }

// When all reference image fetches have completed,
// return the ProductSearchResult list
Tasks.whenAllComplete(fetchReferenceImageTasks)
    // Return the list of ProductSearchResult with product images' HTTP URLs.
    .addOnSuccessListener { apiSource.setResult(productList) }
    // An error occurred so returns it to the caller.
    .addOnFailureListener { apiSource.setException(it) }

Mã nguyên mẫu để hiển thị hình ảnh tham chiếu trên màn hình đã được triển khai trong lớp ProductSearchAdapter cho bạn để bạn có thể tiếp tục chạy lại ứng dụng.

Chạy chiến dịch

Giờ hãy nhấp vào Chạy ( tức thì.png) trong thanh công cụ Android Studio. Sau khi ứng dụng tải, hãy nhấn vào bất kỳ hình ảnh đặt trước nào, chọn một đối tượng được phát hiện, nhấn vào nút Tìm kiếm để xem kết quả tìm kiếm, lần này là với hình ảnh sản phẩm.

Bạn thấy kết quả tìm kiếm sản phẩm có phù hợp với mình không?

25939f5a13eeb3c3.png

9. Xin chúc mừng!

Bạn đã học cách gọi một phần phụ trợ cho Tìm kiếm sản phẩm API Vision để thêm tính năng tìm kiếm hình ảnh sản phẩm vào ứng dụng Android của bạn. Đó là tất cả những gì bạn cần làm để thiết lập và chạy tính năng này!

Khi tiếp tục, bạn có thể muốn tạo phụ trợ của riêng mình bằng cách sử dụng danh sách sản phẩm. Hãy xem lớp học lập trình tiếp theo trong lộ trình học tập về Tìm kiếm hình ảnh sản phẩm để tìm hiểu cách tạo phần phụ trợ của riêng bạn và thiết lập khóa API để gọi khóa đó từ một ứng dụng dành cho thiết bị di động.

Những điều chúng tôi đã đề cập

  • Cách gọi phần phụ trợ Tìm kiếm sản phẩm API Vision từ ứng dụng Android

Bước tiếp theo

Tìm hiểu thêm