1. Trước khi bắt đầu
Trong lớp học lập trình này, bạn sẽ tìm hiểu cách xây dựng một ứng dụng xử lý trường hợp sử dụng công nghệ Thị giác máy tính, phát hiện nội dung chính của một hình ảnh. Việc này thường được gọi là Phân loại hình ảnh hoặc Gắn nhãn hình ảnh.
Điều kiện tiên quyết
Lớp học lập trình này nằm trong lộ trình Bắt đầu sử dụng tính năng phân loại hình ảnh. Nội dung này dành cho các nhà phát triển có kinh nghiệm mới sử dụng công nghệ máy học.
Sản phẩm bạn sẽ tạo ra
- Một ứng dụng Android có khả năng phân loại hình ảnh một bông hoa
- (Không bắt buộc) Ứng dụng iOS có khả năng phân loại hình ảnh của một bông hoa
Bạn cần có
- Android Studio có tại https://developer.android.com/studio cho phần Android của Codelab
- Xcode (có sẵn trong Apple App Store), cho phần iOS của Lớp học lập trình
2. Bắt đầu
Tầm nhìn máy tính là một lĩnh vực trong quy tắc máy học lớn hơn, hoạt động để tìm kiếm các cách mới để máy móc xử lý và trích xuất thông tin từ nội dung của hình ảnh. Trong trường hợp trước đó, máy tính chỉ lưu trữ dữ liệu hình ảnh thực tế, chẳng hạn như giá trị của các pixel tạo nên hình ảnh, thì Vision cho phép máy tính phân tích cú pháp nội dung của hình ảnh và lấy thông tin về những gì chứa trong hình ảnh đó.
Ví dụ: trong trường Thị giác máy tính, hình ảnh mèo có thể được gắn nhãn là chứa mèo, ngoài các pixel tạo nên hình ảnh đó. Có những trường thị giác máy tính khác đi sâu vào vấn đề này hơn, chẳng hạn như Phát hiện đối tượng, ở đó máy tính có thể xác định nhiều mục trong một hình ảnh và lấy các hộp giới hạn cho chúng.
Trong lớp học lập trình này, bạn sẽ tìm hiểu cách xây dựng một ứng dụng xử lý trường hợp sử dụng chính, phát hiện nội dung chính của hình ảnh. Việc này thường được gọi là Phân loại hình ảnh hoặc Gắn nhãn hình ảnh.
Để giữ cho ứng dụng đơn giản nhất có thể, ứng dụng sẽ sử dụng hình ảnh đi kèm với ứng dụng dưới dạng tài nguyên và cho bạn biết phân loại của ứng dụng. Các phần mở rộng trong tương lai có thể là sử dụng Bộ chọn hình ảnh hoặc lấy hình ảnh trực tiếp từ máy ảnh.
Bạn sẽ bắt đầu từ việc xây dựng ứng dụng trên Android bằng Android Studio. (Chuyển sang bước 7 để thực hiện thao tác tương đương trên iOS.)
- Mở Android Studio, chuyển đến trình đơn Tệp và chọn Tạo dự án mới.
- Bạn sẽ được yêu cầu chọn một mẫu dự án. Chọn Hoạt động trống.
- Nhấp vào Next (Tiếp theo) Bạn sẽ được yêu cầu Định cấu hình dự án. Đặt tên gói và tên gói bất kỳ mà bạn muốn, nhưng mã mẫu trong lớp học lập trình này sử dụng tên dự án ImageClassifierStep1 và tên gói com.google.imageclassifierstep1.
- Chọn ngôn ngữ ưa thích của bạn, Kotlin hoặc Java. Phòng thí nghiệm này sử dụng Kotlin, vì vậy, nếu muốn theo dõi chính xác, bạn có thể sẽ chọn Kotlin.
- Khi đã sẵn sàng, hãy nhấp vào Kết thúc. Android Studio sẽ giúp bạn tạo ứng dụng này. Quá trình thiết lập có thể mất vài phút.
3. Nhập Thư viện gắn nhãn hình ảnh của Bộ công cụ máy học
Bộ công cụ máy học (https://developers.google.com/ml-kit) cung cấp một số giải pháp cho nhà phát triển, đáp ứng các tình huống thường gặp trong công nghệ máy học và giúp họ dễ dàng triển khai cũng như hoạt động trên nhiều nền tảng. Bộ công cụ máy học cung cấp một thư viện hoàn chỉnh mà bạn có thể dùng trong ứng dụng này có tên là Gắn nhãn hình ảnh. Thư viện này có mô hình được đào tạo trước để nhận dạng hơn 600 lớp hình ảnh. Vì vậy, việc bắt đầu sử dụng là rất hoàn hảo.
Lưu ý rằng Bộ công cụ máy học cũng cho phép bạn sử dụng các mô hình tùy chỉnh sử dụng cùng một API. Vì vậy, khi bạn đã sẵn sàng, bạn có thể vượt qua phạm vi "bắt đầu" và bắt đầu xây dựng ứng dụng gắn nhãn hình ảnh được cá nhân hóa bằng cách sử dụng mô hình được đào tạo cho tình huống của bạn.
Trong trường hợp này, bạn sẽ xây dựng trình nhận dạng hoa. Khi bạn tạo ứng dụng đầu tiên và hiển thị cho bạn một bức ảnh về hoa, ứng dụng đó sẽ nhận ra đó là một bông hoa. (Sau đó, khi bạn tạo mô hình trình phát hiện hoa của riêng mình, bạn sẽ có thể thả mô hình đó vào ứng dụng của mình với ít thay đổi nhờ Bộ công cụ máy học và mô hình mới cho bạn biết đó là loại hoa nào, chẳng hạn như hoa tulip hoặc hoa hồng.)
- Trong Android Studio, bằng cách sử dụng trình khám phá dự án, hãy nhớ chọn Android ở trên cùng.
- Mở thư mục Gradle Script rồi chọn tệp
build.gradle
cho ứng dụng. Có thể có từ 2 ứng dụng trở lên, vì vậy, hãy đảm bảo rằng bạn đang sử dụng cấp ứng dụng như minh họa ở đây:
- Ở cuối tệp, bạn sẽ thấy một mục có tên là phần phụ thuộc, là nơi lưu trữ danh sách các chế độ cài đặt
implementation
,testImplementation
vàandroidImplementation
. Thêm một tệp mới vào tệp bằng mã này:
implementation 'com.google.mlkit:image-labeling:17.0.3'
(Hãy đảm bảo rằng điều này nằm trong phần dependencies { })
- Bạn sẽ thấy một thanh xuất hiện ở đầu cửa sổ gắn cờ mà
build.gradle
đã thay đổi và bạn cần đồng bộ hóa lại. Hãy tiếp tục và làm điều này. Nếu bạn không nhìn thấy biểu tượng này, hãy tìm biểu tượng voi nhỏ trong thanh công cụ ở trên cùng bên phải rồi nhấp vào biểu tượng đó.
Bây giờ bạn đã nhập Bộ công cụ máy học và bạn đã sẵn sàng để bắt đầu gắn nhãn hình ảnh.
Tiếp theo, bạn sẽ tạo một giao diện người dùng đơn giản để hiển thị hình ảnh và cung cấp cho bạn một nút mà khi người dùng nhấn vào, Công cụ máy học sẽ gọi mô hình gắn nhãn hình ảnh để phân tích cú pháp nội dung của hình ảnh.
4. Xây dựng giao diện người dùng
Trong Android Studio, bạn chỉnh sửa giao diện người dùng cho từng màn hình (hoặc Hoạt động) bằng cách dùng tệp bố cục dựa trên xml. Ứng dụng cơ bản mà bạn đã tạo có một hoạt động duy nhất (mã có trong MainActivity
và bạn sẽ sớm thấy mã đó) và phần khai báo giao diện người dùng sẽ có trong activity_main.xml
.
Bạn có thể tìm thấy mã này trong thư mục res > layout trong trình khám phá dự án của Android – như sau:
Thao tác này sẽ mở một trình chỉnh sửa đầy đủ cho phép bạn thiết kế giao diện người dùng cho Hoạt động của mình. Ở đó có rất nhiều ý định và mục đích của phòng thí nghiệm này là không hướng dẫn bạn cách sử dụng. Để tìm hiểu thêm về trình chỉnh sửa bố cục, hãy xem: https://developer.android.com/studio/write/layout-editor
Để sử dụng phòng thí nghiệm này, hãy chọn Công cụ mã ở góc trên bên phải của trình chỉnh sửa.
Bây giờ bạn sẽ chỉ thấy mã XML trong phần chính của cửa sổ. Thay đổi mã thành:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/imageToLabel"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Label Image"
android:layout_gravity="center"/>
<TextView
android:id="@+id/txtOutput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="start|top" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Thao tác này sẽ cung cấp cho bạn một bố cục siêu đơn giản chứa ImageView
(để hiển thị hình ảnh), Button
(để người dùng nhấn) và TextView
tại đó các nhãn sẽ hiển thị.
Giờ đây, bạn đã xác định giao diện người dùng của mình. Trước khi lập trình, hãy thêm một số hình ảnh dưới dạng tài sản để ứng dụng dự đoán các hình ảnh này.
5. Gói hình ảnh với ứng dụng
Một cách để nhóm các tệp bổ sung với ứng dụng Android là thêm chúng dưới dạng tài sản được biên dịch vào ứng dụng. Để giữ cho ứng dụng này đơn giản, chúng tôi sẽ làm điều này để thêm hình ảnh của một số hoa. Sau đó, bạn có thể mở rộng ứng dụng này để sử dụng Máy ảnh X hoặc các thư viện khác để chụp ảnh và sử dụng ứng dụng đó. Nhưng để đơn giản, chúng tôi hiện chỉ gói ảnh.
- Trong trình khám phá dự án, ở ứng dụng ở trên cùng, hãy nhấp chuột phải rồi chọn Thư mục mới.
- Trên hộp thoại xuất hiện cùng với một danh sách khác chứa các thư mục, hãy chọn src/main/assets.
Sau khi hoàn tất việc này, bạn sẽ thấy thư mục tài sản mới xuất hiện trong trình khám phá dự án:
- Nhấp chuột phải vào thư mục này và bạn sẽ thấy cửa sổ bật lên chứa danh sách các tùy chọn. Một trong những tệp này sẽ là mở thư mục trong hệ thống tệp của bạn. Tìm chế độ phù hợp với hệ điều hành của bạn và chọn chế độ đó. (Trên máy Mac, điều này sẽ là Reveal in Finder) (Mở ra trong Trình tìm kiếm, trên Windows thì Open in Explorer (Mở trong Trình khám phá) và trên Ubuntu sẽ là Show in Files (Hiển thị trong ứng dụng Files).
- Sao chép tệp vào đó. Bạn có thể tải hình ảnh xuống từ các trang web như Pixabay. Bạn nên đổi tên hình ảnh thành hình ảnh đơn giản. Trong trường hợp này, hình ảnh đã được đổi tên
flower1.jpg
.
Sau khi bạn hoàn tất việc này, hãy quay lại Android Studio và bạn sẽ thấy tệp của mình trong thư mục tài sản.
Bây giờ, bạn đã sẵn sàng gắn nhãn hình ảnh này!
6. Viết mã phân loại để gắn nhãn hình ảnh
(Và giờ đây, tất cả chúng ta đều đang chờ đợi, thực hiện công nghệ Thị giác máy tính trên Android!)
- Bạn sẽ viết mã vào tệp
MainActivity
, do đó, hãy tìm mã trong thư mục dự án trong com.google.devrel.imageclassifierstep1 (hoặc bất kỳ vùng chứa tên tương đương nào nếu bạn chọn một vùng chứa tên khác). Xin lưu ý rằng thường có 3 thư mục vùng chứa tên được thiết lập trong dự án Android Studio, một thư mục cho ứng dụng, một thư mục cho Thử nghiệm Android và một thư mục để kiểm tra. Bạn sẽ thấyMainActivity
của mình trong tài khoản không có nội dung mô tả nằm trong dấu ngoặc vuông.
Nếu chọn sử dụng Kotlin, bạn có thể tự hỏi tại sao thư mục mẹ có tên là Java. Đây là một cấu phần phần mềm lịch sử, từ khi Android Studio chỉ có Java. Các phiên bản trong tương lai có thể khắc phục điều này, nhưng đừng lo nếu bạn muốn sử dụng Kotlin, mọi thứ vẫn ổn. Đó chỉ là tên thư mục cho mã nguồn.
- Mở tệp
MainActivity
và bạn sẽ thấy một tệp lớp có tên là MainActivity trong trình chỉnh sửa mã. Phần khai báo sẽ có dạng như sau:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Bên dưới dấu ngoặc nhọn đóng, bạn có thể thêm mã tiện ích không thuộc lớp học nhưng có thể sử dụng được trong lớp. Bạn cần có một tiện ích để đọc tệp từ tài sản dưới dạng bitmap. Tệp này sẽ được dùng để tải hình ảnh bạn đã sao chép vào thư mục tài sản trước đó.
- Thêm mã này:
// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName: String): Bitmap?{
return try {
with(assets.open(fileName)){
BitmapFactory.decodeStream(this)
}
} catch (e: IOException) { null }
}
Tại thời điểm này, Android Studio có thể sẽ khiếu nại và đánh dấu một số mã màu đỏ, như Context
, Bitmap
và IOException
:
Đừng lo lắng! Lý do là bạn chưa nhập thư viện chứa các thư viện đó. Android Studio có một lối tắt tiện dụng.
- Kéo con trỏ qua từ đó rồi nhấn tổ hợp phím ALT + Enter (Option + Enter trên máy Mac) và quá trình nhập sẽ được tạo cho bạn.
- Tiếp theo, bạn có thể tải bitmap từ các tài sản và đặt vào Chế độ xem hình ảnh. Quay lại
onCreateFunction
của MainActivity, hãy thêm mã này ngay bên dưới dòngsetContentView
:
val img: ImageView = findViewById(R.id.imageToLabel)
// assets folder image file name with extension
val fileName = "flower1.jpg"
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
img.setImageBitmap(this)
}
- Như trước đây, một số mã sẽ được đánh dấu màu đỏ. Đặt con trỏ trên dòng đó và sử dụng tổ hợp phím Alt + Enter / Option + Enter để tự động thêm dữ liệu nhập.
- Trong tệp
layout.xml
mà bạn đã tạo trước đó, bạn đã đặt ImageView cho tên imageToLabel, vì vậy dòng đầu tiên sẽ tạo một phiên bản của đối tượng ImageView, có tên là img, sử dụng thông tin bố cục đó. Dịch vụ này tìm thông tin chi tiết bằngfindViewById
, một hàm Android tích hợp sẵn. Sau đó, tệp này sử dụng tên tệpflower1.jpg
để tải hình ảnh từ thư mục tài sản bằng hàmassetsToBitmap
đã tạo ở bước trước. Cuối cùng, lớp này sử dụng lớp trừu tượng bitmap để tải bitmap vào img. - Tệp bố cục có một Chế độ xem văn bản sẽ được dùng để hiển thị các nhãn dự đoán cho hình ảnh. Nhận một đối tượng mã cho mục tiếp theo. Ngay bên dưới mã trước đó, hãy thêm mã sau:
val txtOutput : TextView = findViewById(R.id.txtOutput)
Như trước đây, tính năng này tìm thông tin về tệp bố cục cho chế độ xem văn bản bằng tên (xem XML, trong đó XML được gọi là txtOutput
) và sử dụng thông số đó để tạo thực thể cho đối tượng Chế độ xem văn bản có tên là txtOutput.
Tương tự, bạn sẽ tạo một đối tượng nút để đại diện cho nút đó và tạo bản sao với nội dung tệp bố cục.
Trong tệp bố cục, chúng tôi gọi là nút btnTest
để có thể tạo bản sao như sau:
val btn: Button = findViewById(R.id.btnTest)
Giờ đây, bạn đã khởi chạy tất cả mã và các tùy chọn điều khiển, bước tiếp theo (và cuối cùng) sẽ là sử dụng các tùy chọn đó để dự đoán về hình ảnh.
Trước khi tiếp tục, hãy đảm bảo rằng mã onCreate
của bạn có dạng như sau:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val img: ImageView = findViewById(R.id.imageToLabel)
// assets folder image file name with extension
val fileName = "flower1.jpg"
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
img.setImageBitmap(this)
}
val txtOutput : TextView = findViewById(R.id.txtOutput)
val btn: Button = findViewById(R.id.btnTest)
}
Không có từ khoá nào có màu đỏ, cho biết rằng các từ khoá đó chưa được nhập. Nếu có, hãy quay lại và thực hiện mẹo ALT + Enter để tạo tệp nhập.
Khi sử dụng trình gắn nhãn hình ảnh của Bộ công cụ máy học, bước đầu tiên thường là tạo một đối tượng Tùy chọn để tùy chỉnh hành vi. Bạn sẽ chuyển đổi hình ảnh của mình sang định dạng InputImage mà Bộ công cụ máy học có thể nhận ra. Sau đó, bạn tạo một đối tượng Nhãn để thực hiện dự đoán. Nó sẽ cung cấp cho bạn lệnh gọi lại không đồng bộ với các kết quả, sau đó, bạn có thể phân tích cú pháp.
Trên nút bạn vừa tạo, hãy thực hiện tất cả các thao tác đó trong sự kiện onClickListener
của sự kiện. Dưới đây là mã hoàn chỉnh:
btn.setOnClickListener {
val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)
val image = InputImage.fromBitmap(bitmap!!, 0)
var outputText = ""
labeler.process(image)
.addOnSuccessListener { labels ->
// Task completed successfully
for (label in labels) {
val text = label.text
val confidence = label.confidence
outputText += "$text : $confidence\n"
}
txtOutput.text = outputText
}
.addOnFailureListener { e ->
// Task failed with an exception
}
}
- Khi người dùng nhấp vào nút lần đầu tiên, mã sẽ tạo thực thể cho nhãn bằng ImageLabeling.getClient, chuyển công cụ Gắn nhãn hình ảnh. Thuộc tính này đi kèm với thuộc tính DEFAULT_OPTIONS cho phép chúng tôi thiết lập và chạy nhanh.
- Tiếp theo, Phương thức nhập hình ảnh sẽ được tạo từ bitmap bằng phương thức fromBitmap. Dữ liệu nhập hình ảnh là định dạng mong muốn để xử lý hình ảnh của Bộ công cụ máy học.
- Cuối cùng, trình gắn nhãn sẽ xử lý hình ảnh và cung cấp một lệnh gọi lại không đồng bộ, cả khi thành công hoặc không thành công. Nếu dự đoán thành công, lệnh gọi lại sẽ bao gồm danh sách nhãn. Sau đó, bạn có thể phân tích cú pháp thông qua danh sách các nhãn này để đọc văn bản của nhãn và giá trị tin cậy. Nếu không thành công, Google sẽ gửi lại cho bạn một ngoại lệ để bạn có thể báo cáo cho người dùng.
Và vậy là bạn đã xong! Giờ đây, bạn có thể chạy ứng dụng trên thiết bị Android hoặc bên trong trình mô phỏng. Nếu trước đây bạn chưa từng làm việc này, thì bạn có thể tìm hiểu cách thực hiện tại đây: https://developer.android.com/studio/run/editor
Đây là ứng dụng đang chạy trong trình mô phỏng. Lúc đầu, bạn sẽ thấy hình ảnh và nút, nhãn sẽ trống.
Nhấn nút và bạn sẽ nhận được một bộ nhãn cho hình ảnh.
Ở đây bạn có thể thấy rằng hãng nhạc xác định có khả năng cao là hình ảnh chứa một bông hoa, hoa, cây và bầu trời. Tất cả đều phù hợp và đều thể hiện rằng mô hình đang làm việc để phân tích cú pháp hình ảnh.
Tuy nhiên, họ chưa thể xác định đây là ảnh của hoa cúc. Để làm được điều đó, bạn sẽ cần một mô hình tùy chỉnh được đào tạo về các loại hoa cụ thể, và bạn sẽ thấy cách thực hiện việc đó trong phòng thí nghiệm tiếp theo.
Trong các bước sau, bạn sẽ khám phá cách xây dựng ứng dụng này trên iOS.
7. Tạo công cụ phân loại hình ảnh trên iOS – Bắt đầu
Bạn có thể tạo một ứng dụng tương tự trên iOS bằng cách sử dụng Xcode.
- Khởi chạy Xcode và trong trình đơn tệp, hãy chọn Dự án mới. Bạn sẽ thấy hộp thoại này:
- Chọn Ứng dụng như minh họa và nhấp vào Tiếp theo. Bạn sẽ được yêu cầu chọn các tùy chọn cho dự án. Hãy đặt tên và giá trị nhận dạng tổ chức như tên. Đảm bảo rằng loại giao diện là Storiesboard và ngôn ngữ là Swift như minh họa.
- Nếu muốn triển khai tới điện thoại và đã thiết lập hồ sơ nhà phát triển, bạn có thể thiết lập chế độ cài đặt cho nhóm của mình. Nếu không, hãy để nguyên là Không và bạn có thể sử dụng trình mô phỏng iOS để chạy ứng dụng.
- Nhấp vào Tiếp theo rồi chọn một thư mục để lưu trữ dự án và các tệp trong dự án đó. Nhớ vị trí của dự án này và bạn sẽ cần nó trong bước tiếp theo.
- Đóng Xcode ngay bây giờ vì bạn sẽ mở lại Xcode bằng tệp không gian làm việc khác sau bước tiếp theo.
8. Tích hợp Bộ công cụ máy học bằng Cocoapods
Vì Bộ công cụ máy học cũng hoạt động trên iOS nên bạn có thể dùng bộ công cụ này theo cách tương tự như cách tạo bộ phân loại hình ảnh. Để tích hợp, bạn sẽ sử dụng CocoaPods. Nếu bạn chưa cài đặt ứng dụng này, bạn có thể làm theo hướng dẫn tại https://cocoapods.org/
- Mở thư mục mà bạn đã tạo dự án. Tệp này phải chứa tệp .xcodeproject của bạn.
Tại đây, bạn có thể thấy tệp .xcodeadsense cho biết I\39;m ở đúng vị trí.
- Trong thư mục này, hãy tạo một tệp mới có tên là Podfile. Không có tiện ích, chỉ là Podfile. Trong đó, hãy thêm nội dung sau:
platform :ios, '10.0' target 'ImageClassifierStep1' do pod 'GoogleMLKit/ImageLabeling' end
- Lưu mật khẩu và quay lại thiết bị thanh toán. Trong cùng một thư mục, loại
pod install
. Cocoapods sẽ tải các thư viện và phần phụ thuộc thích hợp xuống, đồng thời tạo một không gian làm việc mới kết hợp dự án của bạn với các phần phụ thuộc bên ngoài của dự án đó.
Xin lưu ý rằng cuối cùng, chế độ này yêu cầu bạn đóng các phiên Xcode và sử dụng tệp không gian làm việc ngay bây giờ. Mở tệp này và Xcode sẽ chạy cùng với dự án gốc của bạn cùng với các phần phụ thuộc bên ngoài.
Bây giờ, bạn đã sẵn sàng chuyển sang bước tiếp theo và tạo giao diện người dùng.
9. Tạo giao diện người dùng iOS bằng cách sử dụng Bảng phân cảnh
- Mở tệp
Main.storyboard
và bạn sẽ thấy bố cục giao diện người dùng với bề mặt thiết kế cho điện thoại. - Ở trên cùng bên phải màn hình là nút + mà bạn có thể sử dụng để thêm các tùy chọn điều khiển. Nhấp vào nút này để tải bảng điều khiển.
- Từ đó, hãy kéo và thả Chế độ xem hình ảnh, Nút và Nhãn vào bề mặt thiết kế. Sắp xếp chúng theo thứ tự từ trên xuống dưới như sau:
- Nhấp đúp vào nút để chỉnh sửa văn bản trên nút từ Nút để Phân loại.
- Kéo các nút điều khiển xung quanh nhãn để tăng kích thước. (Nói về cùng chiều rộng với UIImageView và gấp đôi chiều cao.)
- Khi nhãn vẫn được chọn, hãy nhấp vào nút bộ chọn ở trên cùng bên phải để hiển thị bảng kiểm tra.
- Sau khi bạn thực hiện việc này, hãy tìm chế độ cài đặt Dòng và đảm bảo đã đặt thành 0. Điều này cho phép nhãn hiển thị số lượng dòng động.
Bây giờ, bạn đã sẵn sàng thực hiện bước tiếp theo – kết nối giao diện người dùng với mã để sử dụng ổ cắm và hành động.
10. Tạo hành động và ổ cắm
Khi phát triển iOS bằng bảng phân cảnh, bạn tham khảo thông tin bố cục cho các điều khiển bằng cách sử dụng ổ cắm và xác định mã để chạy khi người dùng thực hiện hành động trên điều khiển bằng cách sử dụng hành động.
Trong bước tiếp theo, bạn sẽ cần tạo đầu ra cho ImageView và Nhãn. Chế độ xem hình ảnh sẽ được tham chiếu trong mã để tải hình ảnh vào đó. Nhãn sẽ được tham chiếu trong mã để đặt văn bản dựa trên dự đoán được lấy từ Bộ công cụ máy học.
- Đóng bảng trình kiểm tra bằng cách nhấp vào tùy chọn điều khiển ở trên cùng bên phải màn hình, rồi nhấp vào nút Thêm trình chỉnh sửa ở bên phải ở ngay bên dưới bảng đó.
- Bạn sẽ có bố cục màn hình khó hiểu, trong đó main.storyboard được mở hai lần. Ở bên trái, trong trình điều hướng dự án, hãy chọn ViewController.swift để mã bộ điều khiển chế độ xem mở ra. Có vẻ như bề mặt thiết kế của bạn đã biến mất khỏi trình chỉnh sửa bảng phân cảnh ở bên trái, nhưng đừng lo lắng, nó vẫn còn ở đó!
- Để quay lại, hãy nhấp vào Xem bộ điều khiển trong cảnh của bộ điều khiển chế độ xem. Cố gắng tạo giao diện người dùng của bạn như thế này – với bảng phân cảnh ở bên trái cho thấy thiết kế của bạn và mã cho ViewController.swift ở bên phải.
- Chọn UIImageView từ giao diện thiết kế ở bên trái, sau đó nhấn phím Control (kéo) đến mã ở bên phải, thả ngay dưới từ khóa
class
(ở dòng 11 trong ảnh chụp màn hình ở trên).
Bạn sẽ thấy một mũi tên khi kéo và khi thả, bạn sẽ nhận được cửa sổ bật lên như sau:
- Điền vào trường Tên dưới dạng "imageView" rồi nhấp vào Kết nối.
- Lặp lại quá trình này với nhãn và đặt tên cho nhãn là "lblOutput."
- Quan trọng: Đối với nút, bạn sẽ làm điều tương tự nhưng đảm bảo bạn đặt loại kết nối thành Thao tác chứ không phải đầu ra!
- Đặt tên cho ứng dụng là tên của "doRating" rồi nhấp vào Kết nối.
Khi bạn hoàn tất, mã sẽ trông như sau: (Lưu ý rằng nhãn và chế độ xem hình ảnh được khai báo là IBOutlet (Interface Builder Outlet) và nút là IBAction (Interface Builder Action).
import UIKit
class ViewController: UIViewController {
@IBAction func doClassification(_ sender: Any) {
}
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var lblOutput: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
- Cuối cùng, hãy gói một hình ảnh với ứng dụng để chúng tôi có thể dễ dàng phân loại. Để làm điều này, hãy kéo tệp từ trình khám phá tệp vào trình khám phá ở bên trái Xcode. Khi bạn thả biểu tượng đó, bạn sẽ thấy cửa sổ bật lên như sau:
- Đảm bảo rằng hộp kiểm trong mục Thêm vào mục tiêu được chọn như minh họa, sau đó nhấp vào Hoàn tất.
Tệp sẽ đi kèm với ứng dụng của bạn và giờ đây bạn có thể dễ dàng phân loại tệp. Bây giờ, bạn đã sẵn sàng mã hóa giao diện người dùng để phân loại hình ảnh!
11. Viết mã cho phân loại hình ảnh
Bây giờ, mọi thứ đã được thiết lập, việc viết mã để thực hiện phân loại hình ảnh thực sự đơn giản.
- Bắt đầu bằng cách đóng trình thiết kế bảng phân cảnh bằng cách nhấp vào X ở góc trên cùng bên trái phía trên bề mặt thiết kế. Điều này sẽ cho phép bạn chỉ tập trung vào mã. Bạn sẽ chỉnh sửa ViewController.swift cho phần còn lại của phòng thí nghiệm này.
- Nhập thư viện MLKitVision và MLKit ImageLabeling bằng cách thêm mã này ở trên cùng, ngay dưới mục nhập UIKit:
import MLKitVision
import MLKitImageLabeling
- Sau đó, trong hàm
viewDidLoad
, hãy khởi tạo Chế độ xem hình ảnh bằng tệp mà chúng ta đã nhóm trong ứng dụng:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imageView.image = UIImage(named:"flower1.jpg")
}
- Tạo một hàm trợ giúp để nhận các nhãn cho hình ảnh, ngay bên dưới
viewDidLoad()
:
func getLabels(with image: UIImage){
- Tạo VisionImage từ hình ảnh. Bộ công cụ máy học sử dụng loại này khi thực hiện phân loại hình ảnh. Vì vậy, trong getGetfunc, hãy thêm mã sau:
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
- Tiếp theo, tạo các tùy chọn cho trình gắn nhãn hình ảnh. Nó sẽ được khởi tạo bằng các tùy chọn này. Trong trường hợp này, bạn chỉ cần đặt một tùy chọn cơ bản của
confidenceThreshold
. Điều này có nghĩa là bạn sẽ chỉ yêu cầu nhãn đó trả lại những nhãn có độ tin cậy từ 0,4 trở lên. Ví dụ: đối với hoa của chúng ta, các lớp như "plant" or "petal" sẽ có độ tin cậy cao, nhưng những lớp như "bóng rổ" hoặc "car" sẽ có mức thấp.
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
- Bây giờ, hãy tạo nhãn bằng cách sử dụng các tùy chọn sau:
let labeler = ImageLabeler.imageLabeler(options: options)
- Sau khi có nhãn, bạn có thể xử lý nhãn. Hệ thống sẽ gửi cho bạn một lệnh gọi lại không đồng bộ có các nhãn (nếu thành công) và lỗi (nếu không thành công). Sau đó, bạn có thể xử lý bằng một hàm khác mà chúng tôi sẽ tạo trong giây lát.
labeler.process(visionImage) { labels, error in
self.processResult(from: labels, error: error)
}
Đừng lo lắng nếu Xcode khiếu nại rằng không có thành viên processResult
nào. Bạn chỉ chưa triển khai điều đó và bạn sẽ làm điều đó tiếp theo.
Để thuận tiện, hãy xem cụm từ getTag đầy đủ:
// This is called when the user presses the button
func getLabels(with image: UIImage){
// Get the image from the UI Image element and set its orientation
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
// Create Image Labeler options, and set the threshold to 0.4
// so we will ignore all classes with a probability of 0.4 or less
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
// Initialize the labeler with these options
let labeler = ImageLabeler.imageLabeler(options: options)
// And then process the image, with the callback going to self.processresult
labeler.process(visionImage) { labels, error in
self.processResult(from: labels, error: error)
}
}
Giờ đây, bạn cần triển khai hàm processResult
. Quy trình này rất đơn giản, vì chúng ta đã có nhãn và một đối tượng lỗi được trả về cho chúng ta. Nhãn phải được nhập vào loại ImageLabel từ Bộ công cụ máy học.
Sau khi hoàn tất, bạn chỉ cần lặp lại tập hợp các nhãn, lấy nội dung mô tả và giá trị tin cậy, rồi thêm chúng vào một var
có tên là labeltexts
. Sau khi lặp lại tất cả, bạn chỉ cần đặt lblOutput.text thành giá trị đó.
Đây là hàm đầy đủ:
// This gets called by the labeler's callback
func processResult(from labels: [ImageLabel]?, error: Error?){
// String to hold the labels
var labeltexts = ""
// Check that we have valid labels first
guard let labels = labels else{
return
}
// ...and if we do we can iterate through the set to get the description and confidence
for label in labels{
let labelText = label.text + " : " + label.confidence.description + "\n"
labeltexts += labelText
}
// And when we're done we can update the UI with the list of labels
lblOutput.text = labeltexts
}
Tất cả công việc còn lại là gọi getLabels
khi người dùng nhấn nút.
Khi tạo hành động này, mọi thứ đã được tạo ra cho bạn, vì vậy, bạn chỉ cần cập nhật IBAction
có tên doClassificaiton
mà bạn đã tạo trước đó để gọi getLabels
.
Dưới đây là mã chỉ cần gọi mã đó có nội dung của imageView:
@IBAction func doClassification(_ sender: Any) {
getLabels(with: imageView.image!)
}
Giờ hãy chạy ứng dụng của bạn và dùng thử. Bạn có thể xem trong thực tế tại đây:
Xin lưu ý rằng bố cục của bạn có thể trông khác nhau tùy thuộc vào thiết bị.
Lớp học lập trình không khám phá các loại bố cục khác nhau trên mỗi thiết bị, đó là một khái niệm khá phức tạp. Nếu bạn không thấy giao diện người dùng đúng cách, hãy quay lại trình chỉnh sửa bảng phân cảnh và ở dưới cùng, bạn sẽ thấy phần Xem dưới dạng:, tại đây bạn có thể chọn một thiết bị cụ thể. Chọn một hình ảnh phù hợp với hình ảnh hoặc thiết bị mà bạn đang thử nghiệm và chỉnh sửa giao diện người dùng cho phù hợp.
Khi ngày càng hiểu rõ hơn về hoạt động phát triển iOS, bạn sẽ tìm hiểu cách sử dụng các quy tắc ràng buộc để đảm bảo giao diện người dùng của bạn nhất quán trên các điện thoại, nhưng lại nằm ngoài phạm vi của phòng thí nghiệm này.
12. Xin chúc mừng!
Bạn hiện đã triển khai một ứng dụng trên cả Android và iOS để có được tầm nhìn cơ bản về máy tính với mô hình chung. Bạn đã thực hiện hầu hết các phần nặng nhọc.
Trong lớp học lập trình tiếp theo, bạn sẽ xây dựng một mô hình tùy chỉnh nhận dạng các loại hoa khác nhau và chỉ với một vài dòng mã, bạn sẽ có thể triển khai mô hình tùy chỉnh trong ứng dụng này để làm cho mô hình này hữu ích hơn!