Xây dựng ứng dụng tách con người, vật nuôi, đồ vật khỏi hình ảnh – Lập trình ứng dụng Android

Link tham khảo API phân đoạn chủ thể: https://developers.google.com/ml-kit/vision/subject-segmentation/android

API phân đoạn chủ thể của Google cho phép các nhà phát triển ứng dụng dễ dàng tách nhiều chủ thể khỏi nền trong một ảnh.

Chủ thể được xác định là người, thú cưng hoặc đối tượng nổi bật nhất ở phía trước của hình ảnh. Nếu 2 đối tượng rất gần hoặc chạm nhau, thì chúng được coi là một đối tượng duy nhất.

Các bạn thực hiện theo các bước sau:

Bước 1: Trong tệp build.gradle ở cấp Project, hãy nhớ đưa kho lưu trữ Maven của Google vào cả hai phần buildscript và allprojects. (Thông thường, khi bạn tạo một ứng dụng đều đã tích hợp phần này, nên có thể bỏ qua bước này).

Bước 2: Thêm thư viện phân đoạn chủ đề ML Kit vào tệp gradle cấp ứng dụng, thường là app/build.gradle:

dependencies {
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
}

Thêm khai báo sau vào tệp AndroidManifest.xml cấp ứng dụng:

<application ...>
...
<meta-data
android:name="com.google.mlkit.vision.DEPENDENCIES"
android:value="subject_segment" />
<!-- To use multiple models: android:value="subject_segment,model2,model3" -->
</application>

Bước 3: Xây dựng giao diện trong tệp activity_main.xml”:

<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="horizontal"
android:gravity="center"
>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/img_1" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/img_2" />
</LinearLayout>

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Chọn ảnh"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/btn_chonanh"
android:layout_margin="5dp"
/>

</androidx.constraintlayout.widget.ConstraintLayout>

Bước 4: Viết chương trình dùng ngôn ngữ Java trong tệp MainActivity.java“:

import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.PickVisualMediaRequest;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.segmentation.subject.Subject;
import com.google.mlkit.vision.segmentation.subject.SubjectSegmentation;
import com.google.mlkit.vision.segmentation.subject.SubjectSegmentationResult;
import com.google.mlkit.vision.segmentation.subject.SubjectSegmenter;
import com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
private ImageView imageView_1;
private ImageView imageView_2;
private Button btn_chonanh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView_1 = findViewById(R.id.img_1);
imageView_2 = findViewById(R.id.img_2);
btn_chonanh = findViewById(R.id.btn_chonanh);
ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> {
// Lệnh được gọi sau khi người dùng chọn một ảnh hoặc đóng trình chọn ảnh.
if (uri != null) {
try {
Bitmap bitmap= MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
imageView_1.setImageBitmap(bitmap);
InputImage image = InputImage.fromBitmap(bitmap, 0);
tach_doi_tuong(image);

} catch (IOException e) {
throw new RuntimeException(e);
}
Log.d("PhotoPicker", "Selected URI: " + uri);
} else {
Log.d("PhotoPicker", "No media selected");
}
});

btn_chonanh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Khởi chạy trình chọn ảnh và cho phép người dùng chỉ chọn hình ảnh.
pickMedia.launch(new PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE)
.build());
}
});
}
private void tach_doi_tuong(InputImage image){
SubjectSegmenterOptions.SubjectResultOptions subjectResultOptions =
new SubjectSegmenterOptions.SubjectResultOptions.Builder()
.enableSubjectBitmap()
.build();

SubjectSegmenterOptions options = new SubjectSegmenterOptions.Builder()
.enableMultipleSubjects(subjectResultOptions)
.build();
SubjectSegmenter segmenter = SubjectSegmentation.getClient(options);

segmenter.process(image).addOnSuccessListener(new OnSuccessListener<SubjectSegmentationResult>() {
@Override
public void onSuccess(SubjectSegmentationResult result) {
List<Subject> subjects = result.getSubjects();

List<Bitmap> bitmaps = new ArrayList<>();
for (Subject subject : subjects) {
bitmaps.add(subject.getBitmap());
}
if (bitmaps.size()>0){
imageView_2.setImageBitmap(bitmaps.get(0));
}

}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {

}
});
}
}

Sau khi xây dựng ứng dụng thành công, sẽ có kết quả như sau:



Như các bạn thấy, đối tượng là ví và con người đã được tách ra khỏi hình ban đầu. Chúc các bạn thực hiện thành công.

Comments