1. Trước khi bắt đầu
Bạn đã xem bản minh hoạ về Google Ống kính chưa? Trong bản minh hoạ đó, bạn có thể hướng camera điện thoại vào một vật thể và tìm nơi bạn có thể mua vật thể đó trên mạng. Nếu 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 lập trình 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 tạo tính năng tìm kiếm hình ảnh sản phẩm trong một ứng dụng 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 tạo bằng Tính năng tìm kiếm sản phẩm của Vision API từ một ứng dụng di động. Phần phụ trợ này có thể lấy một hình ảnh truy vấn và tìm kiếm các sản phẩm tương tự về mặt hình ảnh trong danh mục sản phẩm.
Bạn có thể tìm hiểu về các bước còn lại để tạo một tính năng tìm kiếm sản phẩm bằng hình ảnh, bao gồm cả cách sử dụng Chức năng theo dõi và phát hiện đối tượng của 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 mà họ muốn tìm kiếm, trong lộ trình học tập.
Sản phẩm bạn sẽ tạo ra
|
Kiến thức bạn sẽ học được
- Cách gọi và phân tích cú pháp phản hồi của API Tìm kiếm sản phẩm trong Vision API từ một ứng dụng Android
Bạn cần có
- Một phiên bản Android Studio gần đây (từ phiên bản 4.1.2 trở lên)
- Trình mô phỏng Android Studio hoặc thiết bị Android thực
- Mã mẫu
- Có kiến thức cơ bản về phát triển Android bằng Kotlin
Lớp học lập trình này tập trung vào tính năng Tìm kiếm sản phẩm của Vision API. Các khái niệm và khối mã không liên quan sẽ không được khám phá và chỉ được cung cấp cho bạn để sao chép và dán.
2. Giới thiệu về tính năng Tìm kiếm sản phẩm bằng Vision API
Vision API Product Search 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ự về mặt hình ảnh trong 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 hình ảnh tham khảo mô tả trực quan sản phẩm từ một nhóm quan điểm. Sau đó, bạn có thể thêm những 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, Vision API Product Search hỗ trợ các danh mục sản phẩm sau: đồ gia dụng, quần áo, đồ chơi, hàng đóng gói và danh mục chung.
Khi người dùng truy vấn bộ sản phẩm bằng hình ảnh của riêng họ, Vision API Product Search sẽ áp dụng công nghệ học máy để so sánh sản phẩm trong hình ảnh truy vấn của người dùng với hình ảnh trong bộ sản phẩm của nhà bán lẻ, sau đó trả về danh sách kết quả được xếp hạng theo mức độ tương đồng về mặt hình ảnh và ngữ nghĩa.
3. Tải xuống và chạy ứng dụng khởi đầu
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 một thư mục gốc (odml-pathways-main
) chứa tất cả tài nguyên bạn cần. Trong 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
có 2 thư mục:
starter – Mã khởi đầu mà bạn sẽ xây dựng trong lớp học lập trình này.
final – Mã hoàn chỉnh cho ứng dụng mẫu đã hoàn tất.
Ứng dụng khởi đầu ở đây là ứng dụng mà bạn đã tạo trong lớp học lập trình Phát hiện các đối tượng trong hình ảnh để tạo tính năng tìm kiếm sản phẩm bằng hình ảnh: Android. Ứng dụng này sử dụng Tính năng phát hiện và theo dõi vật thể của Bộ công cụ học máy để phát hiện vật thể trong hình ảnh và hiển thị vật thể đó 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 khởi động vào Android Studio.
Chuyển đến Android Studio, chọn Import Project (Gradle, Eclipse ADT, etc.) (Nhập dự án (Gradle, Eclipse ADT, v.v.)) rồi chọn thư mục starter
trong mã nguồn mà bạn đã tải xuống trước đó.
Chạy ứng dụng khởi đầu
Giờ đây, sau khi nhập dự án vào Android Studio, bạn đã sẵn sàng chạy ứng dụng lần đầu tiên. Kết nối thiết bị Android với máy chủ lưu trữ qua USB hoặc Khởi động trình mô phỏng Android Studio rồi nhấp vào Chạy ( ) trong thanh công cụ của Android Studio.
(Nếu nút này bị vô hiệu hoá, hãy nhớ chỉ nhập starter/app/build.gradle, chứ không nhập toàn bộ kho lưu trữ.)
Giờ đây, ứng dụng sẽ khởi chạy trên thiết bị Android của bạn. Công cụ này đã có khả năng phát hiện đối tượng: phát hiện các mặt hàng thời trang trong hình ảnh và cho bạn biết vị trí của các mặt hàng đó. Hãy thử dùng ảnh đặt sẵn để xác nhận.
Ảnh chụp màn hình của ứng dụng ban đầu có thể phát hiện các đối tượng trong hình ảnh
Tiếp theo, bạn sẽ mở rộng ứng dụng để gửi các đối tượng được phát hiện đến phần phụ trợ Tìm kiếm sản phẩm của Vision API và hiển thị kết quả tìm kiếm trên màn hình.
4. Xử lý việc chọn đối tượng
Cho phép người dùng nhấn vào một đối tượng được 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 trong hình ảnh và bắt đầu tìm kiếm sản phẩm. Ứng dụng khởi đầu đã có khả năng phát hiện các đối tượng trong hình ảnh. Có thể hình ảnh có nhiều đối tượng hoặc đối tượng được phát hiện chỉ chiếm một phần nhỏ trong hình ảnh. Do đó, bạn cần để người dùng nhấn vào một trong các đối tượng được phát hiện để cho biết đối tượng mà họ muốn dùng để tìm kiếm sản phẩm.
Ảnh chụp màn hình các mặt hàng thời trang được phát hiện trong hình ảnh
Để lớp học lập trình này đơn giản và tập trung vào học máy, một số mã Android chung đã được triển khai trong ứng dụng khởi động để giúp bạn phát hiện đối tượng mà người dùng đã nhấn vào. Khung hiển thị hiển thị hình ảnh trong hoạt động chính (ObjectDetectorActivity
) thực sự là một khung hiển thị tuỳ chỉnh (ImageClickableView
) mở rộng ImageView
mặc định của hệ điều hành Android. Lớp này triển khai một số phương thức tiện ích thuận tiện, bao gồm:
fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit))
Đây là một lệnh gọi lại để nhận hình ảnh đã 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 bị cắt này đến phần phụ trợ tìm kiếm sản phẩm.
Thêm mã để xử lý thao tác nhấn của người dùng vào các đối tượng được phát hiện.
Chuyển đến phương thức initViews
trong lớp ObjectDetectorActivity
rồi thêm các dòng này vào cuối phương thức: (Android Studio sẽ cho bạn biết rằng không tìm thấy phương thức startProductImageSearch
. Đừng lo lắng, bạn sẽ triển khai nó sau.)
// Callback received when the user taps on any of the detected objects.
ivPreview.setOnObjectClickListener { objectImage ->
startProductImageSearch(objectImage)
}
onObjectClickListener
được gọi mỗi khi người dùng nhấn vào bất kỳ đối tượng nào được phát hiện trên màn hình. Nó 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 váy ở bên phải, thì trình nghe sẽ được kích hoạt bằng objectImage
như bên dưới.
Ví dụ về hình ảnh bị cắt được truyền đến onObjectClickListener
Gửi hình ảnh đã cắt đến hoạt động tìm kiếm sản phẩm
Giờ đây, 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 của Vision API 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 đã được triển khai trước, vì vậy, 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.
Ảnh chụp màn hình các thành phần giao diện người dùng trên ProductSearchActivity
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 rồi 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ã này thực hiện 3 việc:
- Lấy hình ảnh đã cắt và chuyển đổi thành tệp PNG.
- Bắt đầu
ProductSearchActivity
để thực thi trình tự tìm kiếm sản phẩm. - Đưa URI của hình ảnh bị cắt vào ý định start-activity để
ProductSearchActivity
có thể truy xuất URI đó sau này để dùng làm hình ảnh truy vấn.
Sau đây là 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ợ chỉ được chia thành 2 hoạt động để giúp bạn dễ hiểu hơn trong lớp học lập trình này. Bạn có thể tự quyết định cách triển khai các tính năng này 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à truyề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ì đây là định dạng không mất dữ liệu.
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 khởi đầu.
Chuyển đến phương thức onCreate
và xác nhận rằng mã này đã có ở đó:
// 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
Bây giờ, hãy nhấp vào Chạy ( ) trong thanh công cụ của Android Studio.
Sau khi ứng dụng tải xong, hãy nhấn vào một hình ảnh đặt sẵn bất kỳ rồi chọn một trong các đối tượng được phát hiện.
Kiểm tra để đảm bảo biểu tượng ProductSearchActivity
xuất hiện cùng với hình ảnh mà bạn đã nhấn vào. Nút Tìm kiếm hiện chưa có tác dụng gì, nhưng chúng ta sẽ triển khai nút này ở bước tiếp theo.
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 được phát hiện.
5. Khám phá phần phụ trợ của tính năng 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 lập trình này yêu cầu một phụ trợ tìm kiếm sản phẩm được tạo bằng API Tìm kiếm sản phẩm của Vision. Có 2 cách để thực hiện việc này:
Cách 1: Sử dụng phần phụ trợ minh hoạ đã được triển khai cho bạn
Bạn có thể tiếp tục thực hiện 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 hoạ bằng cách làm theo hướng dẫn bắt đầu nhanh về tính năng Tìm kiếm sản phẩm bằng Vision API.
Cách 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ính năng Tìm kiếm sản phẩm bằng Vision API
Đây là lựa chọn phù hợp cho những người muốn tìm hiểu kỹ về cách tạo một phần phụ trợ tìm kiếm sản phẩm để sau này bạn có thể tạo một phần phụ trợ cho danh mục sản phẩm của riêng mình. Bạn cần có:
- Tài khoản Google Cloud có bật tính năng thanh toán. (Đó có thể là tài khoản dùng thử miễn phí.)
- Có kiến thức về một số khái niệm của Google Cloud, bao gồm 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 sau 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 này khi tương tác với phần phụ trợ tìm kiếm sản phẩm:
- Nhóm sản phẩm: Nhóm sản phẩm là một vùng chứa đơn giản cho một nhóm sản phẩm. Bạn có thể biểu thị danh mục sản phẩm dưới dạng một nhóm sản phẩm và các sản phẩm trong đó.
- Sản phẩm: Sau khi tạo một nhóm sản phẩm, bạn có thể tạo sản phẩm và thêm sản phẩm vào nhóm sản phẩm đó.
- Hình ảnh tham khảo của sản phẩm: Đây là những hình ảnh chứa nhiều góc nhìn về sản phẩm của bạn. Hình ảnh tham khảo được dùng để tìm kiếm các sản phẩm có hình ảnh tương tự.
- Tìm kiếm sản phẩm: Sau khi tạo và lập chỉ mục cho nhóm sản phẩm, bạn có thể truy vấn nhóm sản phẩm bằng Cloud Vision API.
Tìm hiểu về danh mục sản phẩm đặt sẵn
Phần phụ trợ của bản minh hoạ tìm kiếm sản phẩm được dùng trong lớp học lập trình này được tạo bằng tính năng Tìm kiếm sản phẩm của Vision API và một danh mục sản phẩm gồm khoảng một trăm hình ảnh giày và váy. Sau đây là một số hình ảnh trong danh mục:
Ví dụ trong danh mục sản phẩm đặt sẵn
Gọi phần phụ trợ của bản minh hoạ tìm kiếm sản phẩm
Bạn có thể gọi trực tiếp API Tìm kiếm sản phẩm của Vision từ một ứng dụng di động bằng cách thiết lập khoá API Google Cloud và hạn chế quyền truy cập vào khoá API chỉ cho ứng dụng của bạn.
Để đơn giản hoá lớp học lập trình này, 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ợ của bản minh hoạ mà không cần lo lắng về khoá API và hoạt động xác thực. Nó nhận yêu cầu HTTP từ ứng dụng di động, thêm khoá API và chuyển tiếp yêu cầu đến phần phụ trợ của Vision API Product Search. Sau đó, proxy sẽ nhận phản hồi từ phần phụ trợ và trả về phản hồi đó cho ứng dụng di động.
- Điểm cuối của proxy:
https://us-central1-odml-codelabs.cloudfunctions.net/productSearch
- Hành vi của proxy: Thêm một tiêu đề xác thực thích hợp và chuyển tiếp các yêu cầu API đến phần phụ trợ của tính năng Tìm kiếm sản phẩm bằng Vision API. Ví dụ: lệnh gọi API đến
https://us-central1-odml-codelabs.cloudfunctions.net/productSearch/images:annotate
sẽ được chuyển tiếp đếnhttps://vision.googleapis.com/v1/images:annotate
Trong lớp học lập trình này, bạn sẽ sử dụng 2 API của Tính năng tìm kiếm sản phẩm bằng Vision API:
- projects.locations.images.annotate: Gửi hình ảnh truy vấn đến máy chủ và nhận danh sách sản phẩm từ danh mục sản phẩm đặt sẵn có hình ảnh tương tự 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
Tìm hiểu quy trình tìm kiếm sản phẩm
Hãy làm theo quy trình này để thực hiện tìm kiếm sản phẩm bằng phần phụ trợ:
- Mã hoá hình ảnh truy vấn dưới dạng chuỗi base64
- Gọi điểm cuối projects.locations.images.annotate bằng hình ảnh truy vấn
- Nhận mã nhận dạng hình ảnh sản phẩm từ lệnh gọi API trước đó và gửi mã nhận dạng đó đến các điểm cuối projects.locations.products.referenceImages.get để lấy URI của hình ảnh sản phẩm trong kết quả tìm kiếm.
Triển khai lớp ứng dụng khách 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 chuyên dụng có tên là ProductSearchAPIClient
. Một số mã nguyên mẫu đã được triển khai cho bạn trong ứng dụng khởi động:
class ProductSearchAPIClient
: Lớp này hiện chủ yếu là trống nhưng có một số phương thức 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 một thực thể Bitmap thành giá trị đại diện base64 để gửi đến phần phụ trợ tìm kiếm sản phẩmfun annotateImage(image: Bitmap): Task<List<ProductSearchResult>>
: Gọi API projects.locations.images.annotate và phân tích cú pháp phản hồi.fun fetchReferenceImage(searchResult: ProductSearchResult): Task<ProductSearchResult>
: Gọi API projects.locations.products.referenceImages.get và phân tích cú pháp phản hồi.SearchResult.kt
: Tệp này chứa một số lớp dữ liệu để biểu thị các loại do phần phụ trợ Tìm kiếm sản phẩm của Vision API 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 tiếp tục với phần phụ trợ minh hoạ, 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 phụ trợ đó thành điểm cuối Cloud Vision API.
https://vision.googleapis.com/v1
. - VISION_API_KEY là khoá API của Dự án trên đám mây. Vì proxy đã xử lý việc xác thực, nên bạn có thể để trống trường này.
- VISION_API_PROJECT_ID là mã dự án trên đám mây.
odml-codelabs
là dự án trên đám mây nơi triển khai phần phụ trợ minh hoạ. - VISION_API_LOCATION_ID là vị trí trên Cloud 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ần phụ trợ minh hoạ. - VISION_API_PRODUCT_SET_ID là mã nhận dạng của danh mục sản phẩm (còn gọi là "nhóm sản phẩm" theo thuật ngữ Vision API) mà bạn muốn tìm kiếm các sản phẩm tương tự về mặt hình ảnh. Bạn có thể có nhiều danh mục trong một dự án trên Google Cloud.
product_set0
là danh mục sản phẩm đặt sẵn của phần phụ trợ minh hoạ.
7. Gọi API tìm kiếm sản phẩm
Khám phá định dạng yêu cầu và phản hồi API
Bạn có thể tìm thấy các sản phẩm tương tự với một hình ảnh nhất định bằng cách truyền URI Google Cloud Storage, URL trên web hoặc chuỗi được mã hoá base64 của hình ảnh đó đến tính năng Tìm kiếm sản phẩm của Vision API. Trong lớp học lập trình này, bạn sẽ sử dụng lựa chọn chuỗi được mã hoá base64 vì hình ảnh truy vấn của chúng ta chỉ tồn tại trên thiết bị của người dùng.
Bạn cần gửi một yêu cầu POST đến điểm cuối projects.locations.images.annotate bằng nội dung yêu cầu JSON 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"
],
}
}
}
]
}
Bạn cần chỉ định một số tham số::
- base64-encoded-image: Biểu thị base64 (chuỗi ASCII) của dữ liệu nhị phân trong 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ã nhận dạng 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 hình ảnh giày và váy, hãy chỉ định productCategories là apparel-v2
. v2 ở đây có nghĩa là chúng tôi sử dụng mô hình học máy tìm kiếm sản phẩm may mặc phiên bản 2.
Nếu yêu cầu thành công, máy chủ sẽ 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 2 loại kết quả sau:
- productSearchResults – Chứa danh sách các sản phẩm phù hợp cho toàn bộ hình ảnh.
- productGroupedResults – Chứa toạ độ của khung hình chữ nhật và các mặt hàng phù hợp cho từng sản phẩm được xác định trong hình ảnh.
Vì sản phẩm đã được cắt từ hình ảnh gốc, nên bạn sẽ phân tích cú pháp kết quả trong danh sách productSearchResults.
Sau đâ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 riêng biệt của một sản phẩm ở định dạng
projects/{project-id}/locations/{location-id}/products/{product_id}
- product.score: Giá trị cho biết mức độ tương đồng giữa kết quả tìm kiếm và hình ảnh truy vấn. Giá trị càng cao thì mức độ tương đồng càng lớn.
- product.image: Giá trị nhận dạng riêng biệt của hình ảnh tham chiếu của một 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 đó xuất hiện trên màn hình. - product.labels: 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 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 chuyển đổi hình ảnh truy vấn thành 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 cách triển khai sau:
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, hãy tạo một 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ẽ dùng Volley để đưa ra yêu cầu API và trả về kết quả bằng Task API.
Quay lại lớp ProductSearchAPIClient
, tìm phương thức annotateImage
trống rồi thay thế bằng cách triển khai sau:
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 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 này đã 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ã chuẩn phân tích cú pháp phản hồi API và hiển thị các phản hồi đó trên màn hình cho bạn.
Chạy ứng dụng
Bây giờ, hãy nhấp vào Chạy ( ) trong thanh công cụ của Android Studio. Sau khi ứng dụng tải, hãy nhấn vào một hình ảnh đặt sẵn bất kỳ, 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 do phần phụ trợ trả về. Bạn sẽ thấy nội dung như sau:
Ảnh chụp màn hình của màn hình kết quả tìm kiếm sản phẩm
Phần phụ trợ đã trả về một danh sách các sản phẩm tương tự về mặt hình ảnh trong danh mục sản phẩm đặt 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ý do là vì điểm cuối projects.locations.images.annotate chỉ trả về mã nhận dạng hình ảnh sản phẩm như projects/odml-codelabs/locations/us-east1/products/product_id77/referenceImages/image77
. Bạn sẽ cần thực hiện một lệnh gọi API khác đến điểm cuối projects.locations.products.referenceImages.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 hình ảnh tham khảo về sản phẩm
Khám phá định dạng yêu cầu và phản hồi API
Bạn sẽ gửi yêu cầu HTTP GET có nội dung yêu cầu trống đến điểm cuối projects.locations.products.referenceImages.get để nhận 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ủ sẽ trả về mã trạng thái HTTP 200 OK và phản hồi ở định dạng JSON như bên dưới:
{
"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: Giá trị nhận dạng hình ảnh tham khảo
- uri: URI của hình ảnh trên Google Cloud Storage (GCS).
Các hình ảnh tham chiếu của phần phụ trợ tìm kiếm sản phẩm minh hoạ đượ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ị 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, hãy tạo một 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à Task API 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 rồi thay thế bằng cách triển khai sau:
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 lấy một đối tượng searchResult: ProductSearchResult
do điểm cuối tìm kiếm sản phẩm trả về, sau đó thực hiện các bước sau:
- Gọi điểm cuối hình ảnh tham chiếu để lấy URI GCS của hình ảnh tham chiếu.
- Chuyển đổi URI GCS thành URL HTTP.
- Cập nhật thuộc tính
httpUri
của đối tượngsearchResult
bằng URL HTTP này.
Kết nối hai yêu cầu API
Quay lại annotateImage
và sửa đổi để lấy tất cả các URL HTTP của hình ảnh tham chiếu trước khi trả về danh sách ProductSearchResult
cho phương thức gọi.
Tìm dòng này:
// Return the list.
apiSource.setResult(productList)
Sau đó, thay thế bằng cách triển khai sau:
// 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ã chuẩn để 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, vì vậy, bạn có thể tiếp tục chạy lại ứng dụng.
Chạy ứng dụng
Bây giờ, hãy nhấp vào Chạy ( ) trong thanh công cụ của Android Studio. Sau khi ứng dụng tải xong, hãy nhấn vào một hình ảnh đặt sẵn bất kỳ, 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à kết quả có hình ảnh sản phẩm.
Bạn có thấy kết quả tìm kiếm sản phẩm phù hợp với mình không?
9. Xin chúc mừng!
Bạn đã tìm hiểu cách gọi một phần phụ trợ Tìm kiếm sản phẩm của Vision API để thêm chức năng tìm kiếm hình ảnh sản phẩm vào ứng dụng Android. Đó là tất cả những gì bạn cần để ứng dụng hoạt động!
Khi tiếp tục, bạn có thể muốn tạo phần phụ trợ của riêng mình bằng danh mục 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 Tìm kiếm hình ảnh sản phẩm để tìm hiểu cách bạn có thể tạo phần phụ trợ của riêng mình và thiết lập khoá API để gọi phần phụ trợ đó từ một ứng dụng di động.
Nội dung đã đề cập
- Cách gọi phần phụ trợ Tìm kiếm sản phẩm bằng Vision API từ một ứng dụng Android
Các bước tiếp theo
- Hãy xem lớp học lập trình Tạo một phần phụ trợ tìm kiếm hình ảnh sản phẩm bằng tính năng Tìm kiếm sản phẩm của Vision API để tìm hiểu cách tạo phần phụ trợ của riêng bạn.
- Khám phá các lộ trình học tập khác trên trang web Máy học trên thiết bị
- Tạo tính năng tìm kiếm sản phẩm trong ứng dụng Android của riêng bạn