Mulai cepat: Membuat proyek deteksi objek dengan pustaka klien Custom Vision
Mulai menggunakan pustaka klien Visi Kustom untuk .NET. Ikuti langkah-langkah ini untuk menginstal paket dan mencoba contoh kode untuk mem-build model deteksi objek. Anda akan membuat proyek, menambahkan tag, melatih proyek pada gambar sampel, dan menggunakan URL titik akhir prediksi proyek untuk mengujinya secara terprogram. Gunakan contoh ini sebagai templat untuk membuat aplikasi pengenalan gambar Anda sendiri.
Catatan
Jika Anda ingin membangun dan melatih model deteksi objek tanpa menulis kode, lihat panduan berbasis browser.
Dokumentasi referensi | Kode sumber pustaka (pelatihan) (prediksi)| Paket (NuGet) (pelatihan) (prediksi) | Sampel
Prasyarat
- Langganan Azure - Buat langganan secara gratis
- IDE Visual Studio atau versi .NET Core saat ini.
- Setelah Anda memiliki langganan Azure, buat sumber daya Custom Vision di portal Azure untuk membuat sumber daya pelatihan dan prediksi.
- Anda dapat menggunakan tingkat harga gratis (
F0
) untuk percobaan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
- Anda dapat menggunakan tingkat harga gratis (
Membuat variabel lingkungan
Dalam contoh ini, Anda akan menulis kredensial Anda ke variabel lingkungan pada komputer lokal yang menjalankan aplikasi.
Buka portal Microsoft Azure. Jika sumber daya Custom Vision yang Anda buat di bagian Prasyarat berhasil disebarkan, pilih tombol Buka Sumber Daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya. Anda harus mendapatkan kunci untuk sumber daya pelatihan dan prediksi Anda, bersama dengan titik akhir API.
Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya prediksi di portal Azure, yang tercantum sebagai ID Sumber Daya.
Tip
Anda juga menggunakan https://www.customvision.ai/ untuk mendapatkan nilai-nilai ini. Setelah masuk, pilih ikon Pengaturan di kanan atas. Pada halaman Pengaturan , Anda dapat melihat semua kunci, ID sumber daya, dan titik akhir.
Untuk mengatur variabel lingkungan, buka jendela konsol dan ikuti instruksi untuk sistem operasi dan lingkungan pengembangan Anda.
- Untuk mengatur
VISION_TRAINING KEY
variabel lingkungan, gantiyour-training-key
dengan salah satu kunci untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_TRAINING_ENDPOINT
variabel lingkungan, gantiyour-training-endpoint
dengan titik akhir untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_PREDICTION_KEY
variabel lingkungan, gantiyour-prediction-key
dengan salah satu kunci untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_ENDPOINT
variabel lingkungan, gantiyour-prediction-endpoint
dengan titik akhir untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_RESOURCE_ID
variabel lingkungan, gantiyour-resource-id
dengan ID sumber daya untuk sumber daya prediksi Anda.
Penting
Jika Anda menggunakan kunci API, simpan dengan aman di tempat lain, seperti di Azure Key Vault. Jangan sertakan kunci API langsung dalam kode Anda, dan jangan pernah mempostingnya secara publik.
Untuk informasi selengkapnya tentang keamanan layanan AI, lihat Mengautentikasi permintaan ke layanan Azure AI.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id
Setelah menambahkan variabel lingkungan, Anda mungkin perlu memulai ulang program yang sedang berjalan yang akan membaca variabel lingkungan, termasuk jendela konsol.
Menyiapkan
Membuat aplikasi C# baru
Menggunakan Visual Studio, buat aplikasi .NET Core baru.
Memasang pustaka klien
Setelah Anda membuat proyek baru, pasang pustaka klien dengan mengklik kanan solusi proyek di Penjelajah Solusi, lalu pilih Kelola Paket NuGet. Di manajer paket yang terbuka, pilih Telusuri, centang Sertakan prarilis, lalu cari Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training
dan Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction
. Pilih versi terbaru, lalu Pasang.
Tip
Ingin menampilkan seluruh file kode mulai cepat sekaligus? Anda dapat menemukannya di GitHub, yang berisi contoh kode dalam mulai cepat ini.
Dari direktori proyek, buka file program.cs dan tambahkan instruksi using
berikut:
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
Dalam metode Utama aplikasi, buat variabel yang mengambil kunci dan titik akhir sumber daya Anda dari variabel lingkungan. Anda juga akan mendeklarasikan beberapa objek dasar yang akan digunakan nanti.
string trainingEndpoint = Environment.GetEnvironmentVariable("VISION_TRAINING_ENDPOINT");
string trainingKey = Environment.GetEnvironmentVariable("VISION_TRAINING_KEY");
string predictionEndpoint = Environment.GetEnvironmentVariable("VISION_PREDICTION_ENDPOINT");
string predictionKey = Environment.GetEnvironmentVariable("VISION_PREDICTION_KEY");
private static Iteration iteration;
private static string publishedModelName = "CustomODModel";
Dalam metode Utama aplikasi, tambahkan panggilan untuk metode yang digunakan dalam mulai cepat ini. Anda akan mengimplementasikannya nanti.
CustomVisionTrainingClient trainingApi = AuthenticateTraining(trainingEndpoint, trainingKey);
CustomVisionPredictionClient predictionApi = AuthenticatePrediction(predictionEndpoint, predictionKey);
Project project = CreateProject(trainingApi);
AddTags(trainingApi, project);
UploadImages(trainingApi, project);
TrainProject(trainingApi, project);
PublishIteration(trainingApi, project);
TestIteration(predictionApi, project);
Mengautentikasi klien
Dalam metode baru, beri contoh pelatihan dan klien prediksi menggunakan titik akhir dan kunci Anda.
private CustomVisionTrainingClient AuthenticateTraining(string endpoint, string trainingKey, string predictionKey)
{
// Create the Api, passing in the training key
CustomVisionTrainingClient trainingApi = new CustomVisionTrainingClient(new Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.ApiKeyServiceClientCredentials(trainingKey))
{
Endpoint = endpoint
};
return trainingApi;
}
private CustomVisionPredictionClient AuthenticatePrediction(string endpoint, string predictionKey)
{
// Create a prediction endpoint, passing in the obtained prediction key
CustomVisionPredictionClient predictionApi = new CustomVisionPredictionClient(new Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction.ApiKeyServiceClientCredentials(predictionKey))
{
Endpoint = endpoint
};
return predictionApi;
}
Membuat proyek Custom Vision baru
Metode berikutnya ini akan membuat proyek deteksi objek. Proyek yang dibuat akan muncul di situs web Custom Vision. Lihat metode CreateProject untuk menentukan opsi lain saat Anda membuat proyek (dijelaskan dalam panduan portal web Membuat deteksi).
private Project CreateProject(CustomVisionTrainingClient trainingApi)
{
// Find the object detection domain
var domains = trainingApi.GetDomains();
var objDetectionDomain = domains.FirstOrDefault(d => d.Type == "ObjectDetection");
// Create a new project
Console.WriteLine("Creating new project:");
project = trainingApi.CreateProject("My New Project", null, objDetectionDomain.Id);
return project;
}
Menambahkan tag ke proyek
Metode ini mendefinisikan tag yang akan Anda latih modelnya.
private void AddTags(CustomVisionTrainingClient trainingApi, Project project)
{
// Make two tags in the new project
var forkTag = trainingApi.CreateTag(project.Id, "fork");
var scissorsTag = trainingApi.CreateTag(project.Id, "scissors");
}
Mengunggah dan menandai gambar
Pertama, unduh gambar sampel untuk proyek ini. Simpan konten folder gambar sampel ke perangkat lokal Anda.
Saat Anda memberi tag pada gambar dalam proyek deteksi objek, Anda perlu menentukan wilayah setiap objek yang diberi tag menggunakan koordinat yang dinormalisasi. Kode berikut mengaitkan setiap gambar sampel dengan wilayahnya yang diberi tag.
private void UploadImages(CustomVisionTrainingClient trainingApi, Project project)
{
Dictionary<string, double[]> fileToRegionMap = new Dictionary<string, double[]>()
{
// FileName, Left, Top, Width, Height
{"scissors_1", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 } },
{"scissors_2", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 } },
{"scissors_3", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 } },
{"scissors_4", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 } },
{"scissors_5", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 } },
{"scissors_6", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 } },
{"scissors_7", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 } },
{"scissors_8", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 } },
{"scissors_9", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 } },
{"scissors_10", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 } },
{"scissors_11", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 } },
{"scissors_12", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 } },
{"scissors_13", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 } },
{"scissors_14", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 } },
{"scissors_15", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 } },
{"scissors_16", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 } },
{"scissors_17", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 } },
{"scissors_18", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 } },
{"scissors_19", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 } },
{"scissors_20", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 } },
{"fork_1", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 } },
{"fork_2", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 } },
{"fork_3", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 } },
{"fork_4", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 } },
{"fork_5", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 } },
{"fork_6", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 } },
{"fork_7", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 } },
{"fork_8", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 } },
{"fork_9", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 } },
{"fork_10", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 } },
{"fork_11", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 } },
{"fork_12", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 } },
{"fork_13", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 } },
{"fork_14", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 } },
{"fork_15", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 } },
{"fork_16", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 } },
{"fork_17", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 } },
{"fork_18", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 } },
{"fork_19", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 } },
{"fork_20", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 } }
};
Catatan
Untuk proyek Anda sendiri, jika tidak memiliki utilitas klik-dan-seret untuk menandai koordinat wilayah, Anda dapat menggunakan UI web di situs web Custom Vision. Dalam contoh ini, koordinat sudah disediakan.
Kemudian, peta asosiasi ini digunakan untuk mengunggah setiap gambar sampel beserta koordinat wilayahnya. Anda dapat mengunggah hingga 64 gambar dalam satu batch. Anda mungkin perlu mengubah nilai imagePath
untuk menunjuk ke lokasi folder yang tepat.
// Add all images for fork
var imagePath = Path.Combine("Images", "fork");
var imageFileEntries = new List<ImageFileCreateEntry>();
foreach (var fileName in Directory.EnumerateFiles(imagePath))
{
var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List<Region>(new Region[] { new Region(forkTag.Id, region[0], region[1], region[2], region[3]) })));
}
trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));
// Add all images for scissors
imagePath = Path.Combine("Images", "scissors");
imageFileEntries = new List<ImageFileCreateEntry>();
foreach (var fileName in Directory.EnumerateFiles(imagePath))
{
var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List<Region>(new Region[] { new Region(scissorsTag.Id, region[0], region[1], region[2], region[3]) })));
}
trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));
}
Pada titik ini, Anda telah mengunggah semua gambar sampel dan menandai setiap gambar (garpu atau gunting) dengan persegi piksel terkait.
Melatih proyek
Metode ini menciptakan perulangan pelatihan pertama dalam proyek. Metode ini mengajukan kueri layanan sampai pelatihan selesai.
private void TrainProject(CustomVisionTrainingClient trainingApi, Project project)
{
// Now there are images with tags start training the project
Console.WriteLine("\tTraining");
iteration = trainingApi.TrainProject(project.Id);
// The returned iteration will be in progress, and can be queried periodically to see when it has completed
while (iteration.Status == "Training")
{
Thread.Sleep(1000);
// Re-query the iteration to get its updated status
iteration = trainingApi.GetIteration(project.Id, iteration.Id);
}
}
Tip
Berlatih dengan tag yang dipilih
Secara opsional, Anda dapat berlatih hanya dengan subkumpulan tag yang Anda terapkan. Anda mungkin ingin melakukannya jika belum cukup menerapkan tag tertentu, tetapi Anda memiliki cukup banyak tag lain. Dalam panggilan TrainProject, gunakan parameter trainingParameters. Buat TrainingParameters dan atur properti SelectedTags-nya ke daftar ID tag yang ingin Anda gunakan. Model akan dilatih untuk hanya mengenali tag dalam daftar itu.
Menerbitkan perulangan saat ini
Metode ini membuat perulangan model saat ini tersedia untuk kueri. Anda dapat menggunakan nama model sebagai referensi untuk mengirim permintaan prediksi. Anda perlu memasukkan nilai Anda sendiri untuk predictionResourceId
. Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya di portal Azure, yang tercantum sebagai ID Sumber Daya.
private void PublishIteration(CustomVisionTrainingClient trainingApi, Project project)
{
// The iteration is now trained. Publish it to the prediction end point.
var predictionResourceId = Environment.GetEnvironmentVariable("VISION_PREDICTION_RESOURCE_ID");
trainingApi.PublishIteration(project.Id, iteration.Id, publishedModelName, predictionResourceId);
Console.WriteLine("Done!\n");
}
Menguji titik akhir prediksi
Metode ini memuat gambar pengujian, kueri titik akhir model, dan output data prediksi ke konsol.
private void TestIteration(CustomVisionPredictionClient predictionApi, Project project)
{
// Make a prediction against the new project
Console.WriteLine("Making a prediction:");
var imageFile = Path.Combine("Images", "test", "test_image.jpg");
using (var stream = File.OpenRead(imageFile))
{
var result = predictionApi.DetectImage(project.Id, publishedModelName, stream);
// Loop over each prediction and write out the results
foreach (var c in result.Predictions)
{
Console.WriteLine($"\t{c.TagName}: {c.Probability:P1} [ {c.BoundingBox.Left}, {c.BoundingBox.Top}, {c.BoundingBox.Width}, {c.BoundingBox.Height} ]");
}
}
Console.ReadKey();
}
Jalankan aplikasi
Jalankan aplikasi dengan mengeklik tombol Debug di bagian atas jendela IDE.
Saat aplikasi berjalan, aplikasi harus membuka jendela konsol dan menulis output berikut:
Creating new project:
Training
Done!
Making a prediction:
fork: 98.2% [ 0.111609578, 0.184719115, 0.6607002, 0.6637112 ]
scissors: 1.2% [ 0.112389535, 0.119195729, 0.658031344, 0.7023591 ]
Anda kemudian dapat memverifikasi bahwa gambar pengujian (ditemukan dalam Images/Test) diberi tag dengan tepat dan bahwa wilayah deteksi sudah benar. Pada titik ini, Anda dapat menekan tombol apa pun untuk keluar dari aplikasi.
Membersihkan sumber daya
Jika Anda ingin menerapkan proyek deteksi objek Anda sendiri (atau mencoba proyek klasifikasi gambar), hapus proyek deteksi fork/scissors dari contoh ini. Langganan gratis memungkinkan untuk dua proyek Custom Vision.
Di situs web Custom Vision, navigasi ke Proyek dan pilih tempat sampah di bawah Proyek Baru Saya.
Langkah berikutnya
Sekarang Anda telah melakukan setiap langkah proses deteksi objek dalam kode. Sampel ini menjalankan perulangan pelatihan tunggal, tetapi sering kali Anda harus melatih dan menguji model Anda beberapa kali untuk membuatnya lebih akurat. Panduan berikut menangani klasifikasi gambar, tetapi prinsip-prinsipnya mirip dengan deteksi objek.
- Apa itu Custom Vision?
- Kode sumber untuk sampel ini dapat ditemukan di GitHub
- Dokumentasi referensi SDK
Panduan ini menyediakan instruksi dan kode sampel untuk membantu Anda mulai menggunakan pustaka klien Custom Vision untuk Go guna membangun model deteksi objek. Anda akan membuat proyek, menambahkan tag, melatih proyek, dan menggunakan URL titik akhir prediksi proyek untuk mengujinya secara terprogram. Gunakan contoh ini sebagai templat untuk membuat aplikasi pengenalan gambar Anda sendiri.
Catatan
Jika Anda ingin membangun dan melatih model deteksi objek tanpa menulis kode, lihat panduan berbasis browser.
Gunakan pustaka klien Custom Vision untuk Go guna:
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan menandai gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Dokumentasi referensi (pelatihan) (prediksi)
Prasyarat
- Langganan Azure - Buat langganan secara gratis
- Go 1.8+
- Setelah Anda memiliki langganan Azure, buat sumber daya Custom Vision di portal Azure untuk membuat sumber daya pelatihan dan prediksi.
- Anda dapat menggunakan tingkat harga gratis (
F0
) untuk percobaan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
- Anda dapat menggunakan tingkat harga gratis (
Membuat variabel lingkungan
Dalam contoh ini, Anda akan menulis kredensial Anda ke variabel lingkungan pada komputer lokal yang menjalankan aplikasi.
Buka portal Microsoft Azure. Jika sumber daya Custom Vision yang Anda buat di bagian Prasyarat berhasil disebarkan, pilih tombol Buka Sumber Daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya. Anda harus mendapatkan kunci untuk sumber daya pelatihan dan prediksi Anda, bersama dengan titik akhir API.
Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya prediksi di portal Azure, yang tercantum sebagai ID Sumber Daya.
Tip
Anda juga menggunakan https://www.customvision.ai/ untuk mendapatkan nilai-nilai ini. Setelah masuk, pilih ikon Pengaturan di kanan atas. Pada halaman Pengaturan , Anda dapat melihat semua kunci, ID sumber daya, dan titik akhir.
Untuk mengatur variabel lingkungan, buka jendela konsol dan ikuti instruksi untuk sistem operasi dan lingkungan pengembangan Anda.
- Untuk mengatur
VISION_TRAINING KEY
variabel lingkungan, gantiyour-training-key
dengan salah satu kunci untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_TRAINING_ENDPOINT
variabel lingkungan, gantiyour-training-endpoint
dengan titik akhir untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_PREDICTION_KEY
variabel lingkungan, gantiyour-prediction-key
dengan salah satu kunci untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_ENDPOINT
variabel lingkungan, gantiyour-prediction-endpoint
dengan titik akhir untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_RESOURCE_ID
variabel lingkungan, gantiyour-resource-id
dengan ID sumber daya untuk sumber daya prediksi Anda.
Penting
Jika Anda menggunakan kunci API, simpan dengan aman di tempat lain, seperti di Azure Key Vault. Jangan sertakan kunci API langsung dalam kode Anda, dan jangan pernah mempostingnya secara publik.
Untuk informasi selengkapnya tentang keamanan layanan AI, lihat Mengautentikasi permintaan ke layanan Azure AI.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id
Setelah menambahkan variabel lingkungan, Anda mungkin perlu memulai ulang program yang sedang berjalan yang akan membaca variabel lingkungan, termasuk jendela konsol.
Menyiapkan
Menginstal pustaka klien Custom Vision
Untuk menulis aplikasi analisis gambar dengan Custom Vision untuk Go, Anda memerlukan pustaka klien layanan Custom Vision. Jalankan perintah berikut ini di PowerShell :
go get -u github.com/Azure/azure-sdk-for-go/...
atau jika Anda menggunakan dep
, dalam repo run Anda:
dep ensure -add github.com/Azure/azure-sdk-for-go
Mendapatkan sampel gambar
Contoh ini menggunakan gambar dari layanan Azure AI repositori Sampel Python SDK di GitHub. Kloning atau unduh repositori ini ke lingkungan pengembangan Anda. Ingat lokasi foldernya untuk langkah selanjutnya.
Membuat proyek Custom Vision
Buat file baru yang disebut sample.go di direktori proyek yang dipilih, dan buka di editor kode pilihan Anda.
Tambahkan kode berikut ke skrip Anda untuk membuat proyek layanan Custom Vision baru.
Lihat metode CreateProject untuk menentukan opsi lain saat Anda membuat proyek (dijelaskan dalam panduan portal web Membuat deteksi).
import(
"context"
"bytes"
"fmt"
"io/ioutil"
"path"
"log"
"time"
"github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v3.0/customvision/training"
"github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v3.0/customvision/prediction"
)
// retrieve environment variables:
var (
training_key string = os.Getenv("VISION_TRAINING_KEY")
prediction_key string = os.Getenv("VISION_PREDICTION_KEY")
prediction_resource_id = os.Getenv("VISION_PREDICTION_RESOURCE_ID")
endpoint string = os.Getenv("VISION_ENDPOINT")
project_name string = "Go Sample OD Project"
iteration_publish_name = "detectModel"
sampleDataDirectory = "<path to sample images>"
)
func main() {
fmt.Println("Creating project...")
ctx = context.Background()
trainer := training.New(training_key, endpoint)
var objectDetectDomain training.Domain
domains, _ := trainer.GetDomains(ctx)
for _, domain := range *domains.Value {
fmt.Println(domain, domain.Type)
if domain.Type == "ObjectDetection" && *domain.Name == "General" {
objectDetectDomain = domain
break
}
}
fmt.Println("Creating project...")
project, _ := trainer.CreateProject(ctx, project_name, "", objectDetectDomain.ID, "")
Buat tag dalam proyek
Untuk membuat tag klasifikasi ke proyek Anda, tambahkan kode berikut ke akhir sample.go:
# Make two tags in the new project
forkTag, _ := trainer.CreateTag(ctx, *project.ID, "fork", "A fork", string(training.Regular))
scissorsTag, _ := trainer.CreateTag(ctx, *project.ID, "scissors", "Pair of scissors", string(training.Regular))
Mengunggah dan menandai gambar
Saat Anda memberi tag pada gambar dalam proyek deteksi objek, Anda perlu menentukan wilayah setiap objek yang diberi tag menggunakan koordinat yang dinormalisasi.
Catatan
Jika Anda tidak memiliki utilitas klik-dan-seret untuk menandai koordinat wilayah, Anda dapat menggunakan UI web di Customvision.ai. Dalam contoh ini, koordinat sudah disediakan.
Untuk menambahkan gambar, tag, dan wilayah ke proyek, masukkan kode berikut setelah pembuatan tag. Perhatikan bahwa dalam tutorial ini wilayah dalam sebaris dikodekan secara permanen. Wilayah menentukan kotak pembatas dalam koordinat yang dinormalisasi, dan koordinat diberikan dalam urutan: kiri, atas, lebar, tinggi.
forkImageRegions := map[string][4]float64{
"fork_1.jpg": [4]float64{ 0.145833328, 0.3509314, 0.5894608, 0.238562092 },
"fork_2.jpg": [4]float64{ 0.294117659, 0.216944471, 0.534313738, 0.5980392 },
"fork_3.jpg": [4]float64{ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 },
"fork_4.jpg": [4]float64{ 0.254901975, 0.185898721, 0.5232843, 0.594771266 },
"fork_5.jpg": [4]float64{ 0.2365196, 0.128709182, 0.5845588, 0.71405226 },
"fork_6.jpg": [4]float64{ 0.115196079, 0.133611143, 0.676470637, 0.6993464 },
"fork_7.jpg": [4]float64{ 0.164215669, 0.31008172, 0.767156839, 0.410130739 },
"fork_8.jpg": [4]float64{ 0.118872553, 0.318251669, 0.817401946, 0.225490168 },
"fork_9.jpg": [4]float64{ 0.18259804, 0.2136765, 0.6335784, 0.643790841 },
"fork_10.jpg": [4]float64{ 0.05269608, 0.282303959, 0.8088235, 0.452614367 },
"fork_11.jpg": [4]float64{ 0.05759804, 0.0894935, 0.9007353, 0.3251634 },
"fork_12.jpg": [4]float64{ 0.3345588, 0.07315363, 0.375, 0.9150327 },
"fork_13.jpg": [4]float64{ 0.269607842, 0.194068655, 0.4093137, 0.6732026 },
"fork_14.jpg": [4]float64{ 0.143382356, 0.218578458, 0.7977941, 0.295751631 },
"fork_15.jpg": [4]float64{ 0.19240196, 0.0633497, 0.5710784, 0.8398692 },
"fork_16.jpg": [4]float64{ 0.140931368, 0.480016381, 0.6838235, 0.240196079 },
"fork_17.jpg": [4]float64{ 0.305147052, 0.2512582, 0.4791667, 0.5408496 },
"fork_18.jpg": [4]float64{ 0.234068632, 0.445702642, 0.6127451, 0.344771236 },
"fork_19.jpg": [4]float64{ 0.219362751, 0.141781077, 0.5919118, 0.6683006 },
"fork_20.jpg": [4]float64{ 0.180147052, 0.239820287, 0.6887255, 0.235294119 },
}
scissorsImageRegions := map[string][4]float64{
"scissors_1.jpg": [4]float64{ 0.4007353, 0.194068655, 0.259803921, 0.6617647 },
"scissors_2.jpg": [4]float64{ 0.426470578, 0.185898721, 0.172794119, 0.5539216 },
"scissors_3.jpg": [4]float64{ 0.289215684, 0.259428144, 0.403186262, 0.421568632 },
"scissors_4.jpg": [4]float64{ 0.343137264, 0.105833367, 0.332107842, 0.8055556 },
"scissors_5.jpg": [4]float64{ 0.3125, 0.09766343, 0.435049027, 0.71405226 },
"scissors_6.jpg": [4]float64{ 0.379901975, 0.24308826, 0.32107842, 0.5718954 },
"scissors_7.jpg": [4]float64{ 0.341911763, 0.20714055, 0.3137255, 0.6356209 },
"scissors_8.jpg": [4]float64{ 0.231617644, 0.08459154, 0.504901946, 0.8480392 },
"scissors_9.jpg": [4]float64{ 0.170343131, 0.332957536, 0.767156839, 0.403594762 },
"scissors_10.jpg": [4]float64{ 0.204656869, 0.120539248, 0.5245098, 0.743464053 },
"scissors_11.jpg": [4]float64{ 0.05514706, 0.159754932, 0.799019635, 0.730392158 },
"scissors_12.jpg": [4]float64{ 0.265931368, 0.169558853, 0.5061275, 0.606209159 },
"scissors_13.jpg": [4]float64{ 0.241421565, 0.184264734, 0.448529422, 0.6830065 },
"scissors_14.jpg": [4]float64{ 0.05759804, 0.05027781, 0.75, 0.882352948 },
"scissors_15.jpg": [4]float64{ 0.191176474, 0.169558853, 0.6936275, 0.6748366 },
"scissors_16.jpg": [4]float64{ 0.1004902, 0.279036, 0.6911765, 0.477124184 },
"scissors_17.jpg": [4]float64{ 0.2720588, 0.131977156, 0.4987745, 0.6911765 },
"scissors_18.jpg": [4]float64{ 0.180147052, 0.112369314, 0.6262255, 0.6666667 },
"scissors_19.jpg": [4]float64{ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 },
"scissors_20.jpg": [4]float64{ 0.158088237, 0.04047389, 0.6691176, 0.843137264 },
}
Kemudian, gunakan peta asosiasi ini untuk mengunggah setiap gambar sampel dengan koordinat wilayahnya (Anda dapat mengunggah hingga 64 gambar dalam satu batch). Tambahkan kode berikut.
Catatan
Anda harus mengubah jalur ke gambar berdasarkan tempat Anda mengunduh proyek Sampel Go SDK layanan Azure AI sebelumnya.
// Go through the data table above and create the images
fmt.Println("Adding images...")
var fork_images []training.ImageFileCreateEntry
for file, region := range forkImageRegions {
imageFile, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "fork", file))
regiontest := forkImageRegions[file]
imageRegion := training.Region{
TagID: forkTag.ID,
Left: ®iontest[0],
Top: ®iontest[1],
Width: ®iontest[2],
Height: ®iontest[3],
}
var fileName string = file
fork_images = append(fork_images, training.ImageFileCreateEntry{
Name: &fileName,
Contents: &imageFile,
Regions: &[]training.Region{imageRegion}
})
}
fork_batch, _ := trainer.CreateImagesFromFiles(ctx, *project.ID, training.ImageFileCreateBatch{
Images: &fork_images,
})
if (!*fork_batch.IsBatchSuccessful) {
fmt.Println("Batch upload failed.")
}
var scissor_images []training.ImageFileCreateEntry
for file, region := range scissorsImageRegions {
imageFile, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "scissors", file))
imageRegion := training.Region {
TagID:scissorsTag.ID,
Left:®ion[0],
Top:®ion[1],
Width:®ion[2],
Height:®ion[3],
}
scissor_images = append(scissor_images, training.ImageFileCreateEntry {
Name: &file,
Contents: &imageFile,
Regions: &[]training.Region{ imageRegion },
})
}
scissor_batch, _ := trainer.CreateImagesFromFiles(ctx, *project.ID, training.ImageFileCreateBatch{
Images: &scissor_images,
})
if (!*scissor_batch.IsBatchSuccessful) {
fmt.Println("Batch upload failed.")
}
Melatih dan menerbitkan proyek
Kode ini membuat perulangan pertama dari model prediksi dan kemudian menerbitkan perulangan itu ke titik akhir prediksi. Nama yang diberikan pada perulangan yang dipublikasikan dapat digunakan untuk mengirim permintaan prediksi. Perulangan tidak tersedia di titik akhir prediksi hingga diterbitkan.
iteration, _ := trainer.TrainProject(ctx, *project.ID)
fmt.Println("Training status:", *iteration.Status)
for {
if *iteration.Status != "Training" {
break
}
time.Sleep(5 * time.Second)
iteration, _ = trainer.GetIteration(ctx, *project.ID, *iteration.ID)
fmt.Println("Training status:", *iteration.Status)
}
trainer.PublishIteration(ctx, *project.ID, *iteration.ID, iteration_publish_name, prediction_resource_id))
Menggunakan titik akhir prediksi
Untuk mengirim gambar ke titik akhir prediksi dan mengambil prediksi, tambahkan kode berikut ke akhir file:
fmt.Println("Predicting...")
predictor := prediction.New(prediction_key, endpoint)
testImageData, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "Test", "test_od_image.jpg"))
results, _ := predictor.DetectImage(ctx, *project.ID, iteration_publish_name, ioutil.NopCloser(bytes.NewReader(testImageData)), "")
for _, prediction := range *results.Predictions {
boundingBox := *prediction.BoundingBox
fmt.Printf("\t%s: %.2f%% (%.2f, %.2f, %.2f, %.2f)",
*prediction.TagName,
*prediction.Probability * 100,
*boundingBox.Left,
*boundingBox.Top,
*boundingBox.Width,
*boundingBox.Height)
fmt.Println("")
}
}
Jalankan aplikasi
Jalankan sample.go.
go run sample.go
Output aplikasi akan muncul di konsol. Anda kemudian dapat memverifikasi bahwa gambar pengujian (ditemukan dalam sampel/visi/gambar/Tes) ditandai dengan tepat dan bahwa wilayah deteksi sudah benar.
Membersihkan sumber daya
Jika Anda ingin menerapkan proyek deteksi objek Anda sendiri (atau mencoba proyek klasifikasi gambar), hapus proyek deteksi fork/scissors dari contoh ini. Langganan gratis memungkinkan untuk dua proyek Custom Vision.
Di situs web Custom Vision, navigasi ke Proyek dan pilih tempat sampah di bawah Proyek Baru Saya.
Langkah berikutnya
Sekarang Anda telah melakukan setiap langkah proses deteksi objek dalam kode. Sampel ini menjalankan perulangan pelatihan tunggal, tetapi sering kali Anda harus melatih dan menguji model Anda beberapa kali untuk membuatnya lebih akurat. Panduan berikut menangani klasifikasi gambar, tetapi prinsip-prinsipnya mirip dengan deteksi objek.
Mulailah menggunakan pustaka klien Visual Kustom Java untuk membuat model deteksi objek. Ikuti langkah-langkah berikut untuk memasang paket dan mencoba contoh kode untuk tugas-tugas dasar. Gunakan contoh ini sebagai templat untuk membuat aplikasi pengenalan gambar Anda sendiri.
Catatan
Jika Anda ingin membangun dan melatih model deteksi objek tanpa menulis kode, lihat panduan berbasis browser.
Gunakan pustaka klien Visual Kustom untuk Java untuk:
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan menandai gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Dokumentasi referensi | Kode sumber pustaka (pelatihan) (prediksi)| Artefak (Maven) (pelatihan) (prediksi) | Sampel
Prasyarat
- Langganan Azure - buat langganan gratis
- Versi saat ini dari Java Development Kit (JDK)
- Alat build Gradle, atau manajer dependensi lainnya.
- Setelah Anda memiliki langganan Azure, buat sumber daya Custom Vision di portal Azure untuk membuat sumber daya pelatihan dan prediksi.
- Anda dapat menggunakan tingkat harga gratis (
F0
) untuk percobaan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
- Anda dapat menggunakan tingkat harga gratis (
Membuat variabel lingkungan
Dalam contoh ini, Anda akan menulis kredensial Anda ke variabel lingkungan pada komputer lokal yang menjalankan aplikasi.
Buka portal Microsoft Azure. Jika sumber daya Custom Vision yang Anda buat di bagian Prasyarat berhasil disebarkan, pilih tombol Buka Sumber Daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya. Anda harus mendapatkan kunci untuk sumber daya pelatihan dan prediksi Anda, bersama dengan titik akhir API.
Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya prediksi di portal Azure, yang tercantum sebagai ID Sumber Daya.
Tip
Anda juga menggunakan https://www.customvision.ai/ untuk mendapatkan nilai-nilai ini. Setelah masuk, pilih ikon Pengaturan di kanan atas. Pada halaman Pengaturan , Anda dapat melihat semua kunci, ID sumber daya, dan titik akhir.
Untuk mengatur variabel lingkungan, buka jendela konsol dan ikuti instruksi untuk sistem operasi dan lingkungan pengembangan Anda.
- Untuk mengatur
VISION_TRAINING KEY
variabel lingkungan, gantiyour-training-key
dengan salah satu kunci untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_TRAINING_ENDPOINT
variabel lingkungan, gantiyour-training-endpoint
dengan titik akhir untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_PREDICTION_KEY
variabel lingkungan, gantiyour-prediction-key
dengan salah satu kunci untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_ENDPOINT
variabel lingkungan, gantiyour-prediction-endpoint
dengan titik akhir untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_RESOURCE_ID
variabel lingkungan, gantiyour-resource-id
dengan ID sumber daya untuk sumber daya prediksi Anda.
Penting
Jika Anda menggunakan kunci API, simpan dengan aman di tempat lain, seperti di Azure Key Vault. Jangan sertakan kunci API langsung dalam kode Anda, dan jangan pernah mempostingnya secara publik.
Untuk informasi selengkapnya tentang keamanan layanan AI, lihat Mengautentikasi permintaan ke layanan Azure AI.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id
Setelah menambahkan variabel lingkungan, Anda mungkin perlu memulai ulang program yang sedang berjalan yang akan membaca variabel lingkungan, termasuk jendela konsol.
Menyiapkan
Buat proyek Gradle baru
Di jendela konsol (seperti cmd, PowerShell, atau Bash), buat direktori baru untuk aplikasi Anda, dan buka direktori tersebut.
mkdir myapp && cd myapp
Jalankan perintah gradle init
dari direktori yang berfungsi. Perintah ini akan membuat file build penting untuk Gradle, termasuk build.gradle.kts yang digunakan saat runtime bahasa umum untuk membuat dan mengonfigurasi aplikasi Anda.
gradle init --type basic
Saat diminta untuk memilih DSL, pilih Kotlin.
Memasang pustaka klien
Temukan build.gradle.kts lalu buka dengan IDE atau editor teks pilihan Anda. Lalu, salin dalam konfigurasi build berikut. Konfigurasi ini mendefinisikan proyek sebagai aplikasi Java yang titik masuknya adalah kelas CustomVisionQuickstart. Konfigurasi ini mengimpor pustaka Visual Kustom.
plugins {
java
application
}
application {
mainClassName = "CustomVisionQuickstart"
}
repositories {
mavenCentral()
}
dependencies {
compile(group = "com.azure", name = "azure-cognitiveservices-customvision-training", version = "1.1.0-preview.2")
compile(group = "com.azure", name = "azure-cognitiveservices-customvision-prediction", version = "1.1.0-preview.2")
}
Membuat file Java
Dari direktori kerja Anda, jalankan perintah berikut ini untuk membuat folder sumber proyek:
mkdir -p src/main/java
Navigasi ke folder baru dan buat file bernama CustomVisionQuickstart.java. Buka di editor atau IDE pilihan Anda, lalu tambahkan pernyataan import
berikut:
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import com.google.common.io.ByteStreams;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Classifier;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Domain;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.DomainType;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.ImageFileCreateBatch;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.ImageFileCreateEntry;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Iteration;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Project;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Region;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.TrainProjectOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.CustomVisionTrainingClient;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.Trainings;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.CustomVisionTrainingManager;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.models.ImagePrediction;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.models.Prediction;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.CustomVisionPredictionClient;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.CustomVisionPredictionManager;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Tag;
Tip
Ingin menampilkan seluruh file kode mulai cepat sekaligus? Anda dapat menemukannya di GitHub, yang berisi contoh kode dalam mulai cepat ini.
Di kelas CustomVisionQuickstart aplikasi, buat variabel yang mengambil kunci dan titik akhir sumber daya Anda dari variabel lingkungan.
// retrieve environment variables
final static String trainingApiKey = System.getenv("VISION_TRAINING_KEY");
final static String trainingEndpoint = System.getenv("VISION_TRAINING_ENDPOINT");
final static String predictionApiKey = System.getenv("VISION_PREDICTION_KEY");
final static String predictionEndpoint = System.getenv("VISION_PREDICTION_ENDPOINT");
final static String predictionResourceId = System.getenv("VISION_PREDICTION_RESOURCE_ID");
Dalam metode utama aplikasi, tambahkan panggilan untuk metode yang digunakan dalam mulai cepat ini. Anda akan menentukannya nanti.
Project projectOD = createProjectOD(trainClient);
addTagsOD(trainClient, projectOD);
uploadImagesOD(trainClient, projectOD);
trainProjectOD(trainClient, projectOD);
publishIterationOD(trainClient, project);
testProjectOD(predictor, projectOD);
Model objek
Kelas dan antarmuka berikut menangani beberapa fitur utama pustaka klien Java Visual Kustom.
Nama | Deskripsi |
---|---|
CustomVisionTrainingClient | Kelas ini menangani pembuatan, pelatihan, dan penerbitan model Anda. |
CustomVisionPredictionClient | Kelas ini menangani kueri model Anda untuk prediksi deteksi objek. |
ImagePrediction | Kelas ini menentukan satu prediksi objek pada satu gambar. Ini mencakup properti untuk ID dan nama objek, lokasi kotak batas objek, serta skor keyakinan. |
Contoh kode
Cuplikan kode ini memperlihatkan cara melakukan berbagai tugas berikut dengan pustaka klien Visual Kustom untuk Java:
- Autentikasi klien
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan memberi tag pada gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Mengautentikasi klien
Dalam metode utama Anda, iberi contoh pelatihan dan prediksi klien menggunakan titik akhir dan kunci Anda.
// Authenticate
CustomVisionTrainingClient trainClient = CustomVisionTrainingManager
.authenticate(trainingEndpoint, trainingApiKey)
.withEndpoint(trainingEndpoint);
CustomVisionPredictionClient predictor = CustomVisionPredictionManager
.authenticate(predictionEndpoint, predictionApiKey)
.withEndpoint(predictionEndpoint);
Membuat proyek Custom Vision baru
Metode berikutnya ini akan membuat proyek deteksi objek. Proyek yang dibuat akan muncul di situs web Visual Kustom yang Anda kunjungi sebelumnya. Lihat overload metode CreateProject untuk menentukan opsi lain saat Anda membuat proyek (dijelaskan dalam panduan portal web Membuat detektor).
public static Project createProjectOD(CustomVisionTrainingClient trainClient) {
Trainings trainer = trainClient.trainings();
// find the object detection domain to set the project type
Domain objectDetectionDomain = null;
List<Domain> domains = trainer.getDomains();
for (final Domain domain : domains) {
if (domain.type() == DomainType.OBJECT_DETECTION) {
objectDetectionDomain = domain;
break;
}
}
if (objectDetectionDomain == null) {
System.out.println("Unexpected result; no objects were detected.");
}
System.out.println("Creating project...");
// create an object detection project
Project project = trainer.createProject().withName("Sample Java OD Project")
.withDescription("Sample OD Project").withDomainId(objectDetectionDomain.id())
.withClassificationType(Classifier.MULTILABEL.toString()).execute();
return project;
}
Menambahkan tag ke proyek Anda
Metode ini mendefinisikan tag yang akan Anda latih modelnya.
public static void addTagsOD(CustomVisionTrainingClient trainClient, Project project) {
Trainings trainer = trainClient.trainings();
// create fork tag
Tag forkTag = trainer.createTag().withProjectId(project.id()).withName("fork").execute();
// create scissors tag
Tag scissorsTag = trainer.createTag().withProjectId(project.id()).withName("scissor").execute();
}
Mengunggah dan menandai gambar
Pertama, unduh gambar sampel untuk proyek ini. Simpan konten folder gambar sampel ke perangkat lokal Anda.
Catatan
Apakah Anda memerlukan serangkaian gambar yang lebih luas untuk menyelesaikan latihan Anda? Trove, proyek Microsoft Garage, memungkinkan Anda mengumpulkan dan membeli serangkaian gambar untuk tujuan pelatihan. Setelah mengumpulkan gambar, Anda dapat mengunduhnya lalu mengimpornya ke proyek Custom Vision dengan cara yang biasa. Kunjungi halaman Trove untuk mempelajari selengkapnya.
Saat Anda memberi tag pada gambar dalam proyek deteksi objek, Anda perlu menentukan wilayah setiap objek yang diberi tag menggunakan koordinat yang dinormalisasi. Kode berikut mengaitkan setiap gambar sampel dengan wilayahnya yang diberi tag.
Catatan
Jika Anda tidak memiliki utilitas klik-dan-seret untuk menandai koordinat wilayah, Anda dapat menggunakan UI web di Customvision.ai. Dalam contoh ini, koordinat sudah disediakan.
public static void uploadImagesOD(CustomVisionTrainingClient trainClient, Project project) {
// Mapping of filenames to their respective regions in the image. The
// coordinates are specified
// as left, top, width, height in normalized coordinates. I.e. (left is left in
// pixels / width in pixels)
// This is a hardcoded mapping of the files we'll upload along with the bounding
// box of the object in the
// image. The boudning box is specified as left, top, width, height in
// normalized coordinates.
// Normalized Left = Left / Width (in Pixels)
// Normalized Top = Top / Height (in Pixels)
// Normalized Bounding Box Width = (Right - Left) / Width (in Pixels)
// Normalized Bounding Box Height = (Bottom - Top) / Height (in Pixels)
HashMap<String, double[]> regionMap = new HashMap<String, double[]>();
regionMap.put("scissors_1.jpg", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 });
regionMap.put("scissors_2.jpg", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 });
regionMap.put("scissors_3.jpg", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 });
regionMap.put("scissors_4.jpg", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 });
regionMap.put("scissors_5.jpg", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 });
regionMap.put("scissors_6.jpg", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 });
regionMap.put("scissors_7.jpg", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 });
regionMap.put("scissors_8.jpg", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 });
regionMap.put("scissors_9.jpg", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 });
regionMap.put("scissors_10.jpg", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 });
regionMap.put("scissors_11.jpg", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 });
regionMap.put("scissors_12.jpg", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 });
regionMap.put("scissors_13.jpg", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 });
regionMap.put("scissors_14.jpg", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 });
regionMap.put("scissors_15.jpg", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 });
regionMap.put("scissors_16.jpg", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 });
regionMap.put("scissors_17.jpg", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 });
regionMap.put("scissors_18.jpg", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 });
regionMap.put("scissors_19.jpg", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 });
regionMap.put("scissors_20.jpg", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 });
regionMap.put("fork_1.jpg", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 });
regionMap.put("fork_2.jpg", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 });
regionMap.put("fork_3.jpg", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 });
regionMap.put("fork_4.jpg", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 });
regionMap.put("fork_5.jpg", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 });
regionMap.put("fork_6.jpg", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 });
regionMap.put("fork_7.jpg", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 });
regionMap.put("fork_8.jpg", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 });
regionMap.put("fork_9.jpg", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 });
regionMap.put("fork_10.jpg", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 });
regionMap.put("fork_11.jpg", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 });
regionMap.put("fork_12.jpg", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 });
regionMap.put("fork_13.jpg", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 });
regionMap.put("fork_14.jpg", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 });
regionMap.put("fork_15.jpg", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 });
regionMap.put("fork_16.jpg", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 });
regionMap.put("fork_17.jpg", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 });
regionMap.put("fork_18.jpg", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 });
regionMap.put("fork_19.jpg", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 });
regionMap.put("fork_20.jpg", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 });
Blok kode berikutnya menambahkan gambar ke proyek. Anda harus mengubah argumen panggilan GetImage
agar mengarah ke lokasi folder fork dan gunting yang Anda unduh.
Trainings trainer = trainClient.trainings();
System.out.println("Adding images...");
for (int i = 1; i <= 20; i++) {
String fileName = "fork_" + i + ".jpg";
byte[] contents = GetImage("/fork", fileName);
AddImageToProject(trainer, project, fileName, contents, forkTag.id(), regionMap.get(fileName));
}
for (int i = 1; i <= 20; i++) {
String fileName = "scissors_" + i + ".jpg";
byte[] contents = GetImage("/scissors", fileName);
AddImageToProject(trainer, project, fileName, contents, scissorsTag.id(), regionMap.get(fileName));
}
}
Cuplikan kode sebelumnya menggunakan dua fungsi bantuan yang mengambil gambar sebagai aliran sumber daya dan mengunggahnya ke layanan (Anda dapat mengunggah hingga 64 gambar dalam satu batch). Tentukan metode ini.
private static void AddImageToProject(Trainings trainer, Project project, String fileName, byte[] contents,
UUID tag, double[] regionValues) {
System.out.println("Adding image: " + fileName);
ImageFileCreateEntry file = new ImageFileCreateEntry().withName(fileName).withContents(contents);
ImageFileCreateBatch batch = new ImageFileCreateBatch().withImages(Collections.singletonList(file));
// If Optional region is specified, tack it on and place the tag there,
// otherwise
// add it to the batch.
if (regionValues != null) {
Region region = new Region().withTagId(tag).withLeft(regionValues[0]).withTop(regionValues[1])
.withWidth(regionValues[2]).withHeight(regionValues[3]);
file = file.withRegions(Collections.singletonList(region));
} else {
batch = batch.withTagIds(Collections.singletonList(tag));
}
trainer.createImagesFromFiles(project.id(), batch);
}
private static byte[] GetImage(String folder, String fileName) {
try {
return ByteStreams.toByteArray(CustomVisionSamples.class.getResourceAsStream(folder + "/" + fileName));
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return null;
}
Melatih proyek
Metode ini menciptakan perulangan pelatihan pertama dalam proyek. Metode ini mengajukan kueri layanan sampai pelatihan selesai.
public static String trainProjectOD(CustomVisionTrainingClient trainClient, Project project) {
Trainings trainer = trainClient.trainings();
System.out.println("Training...");
Iteration iteration = trainer.trainProject(project.id(), new TrainProjectOptionalParameter());
while (iteration.status().equals("Training")) {
System.out.println("Training Status: " + iteration.status());
Thread.sleep(5000);
iteration = trainer.getIteration(project.id(), iteration.id());
}
System.out.println("Training Status: " + iteration.status());
}
Menerbitkan perulangan saat ini
Metode ini membuat perulangan model saat ini tersedia untuk kueri. Anda dapat menggunakan nama model sebagai referensi untuk mengirim permintaan prediksi. Anda perlu memasukkan nilai Anda sendiri untuk predictionResourceId
. Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya di portal Azure, yang tercantum sebagai ID Sumber Daya.
public static String publishIterationOD(CustomVisionTrainingClient trainClient, Project project) {
Trainings trainer = trainClient.trainings();
// The iteration is now trained. Publish it to the prediction endpoint.
String publishedModelName = "myModel";
String predictionID = "<your-prediction-resource-ID>";
trainer.publishIteration(project.id(), iteration.id(), publishedModelName, predictionID);
return publishedModelName;
}
Menguji titik akhir prediksi
Metode ini memuat gambar pengujian, kueri titik akhir model, dan output data prediksi ke konsol.
public static void testProjectOD(CustomVisionPredictionClient predictor, Project project) {
// load test image
byte[] testImage = GetImage("/ObjectTest", "test_image.jpg");
// predict
ImagePrediction results = predictor.predictions().detectImage().withProjectId(project.id())
.withPublishedName(publishedModelName).withImageData(testImage).execute();
for (Prediction prediction : results.predictions()) {
System.out.println(String.format("\t%s: %.2f%% at: %.2f, %.2f, %.2f, %.2f", prediction.tagName(),
prediction.probability() * 100.0f, prediction.boundingBox().left(), prediction.boundingBox().top(),
prediction.boundingBox().width(), prediction.boundingBox().height()));
}
}
Jalankan aplikasi
Anda dapat membuat aplikasi dengan:
gradle build
Jalankan aplikasi dengan gradle run
perintah:
gradle run
Membersihkan sumber daya
Jika Anda ingin membersihkan dan menghapus langganan layanan Azure AI, Anda dapat menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya.
Jika Anda ingin menerapkan proyek deteksi objek Anda sendiri (atau mencoba proyek klasifikasi gambar), hapus proyek deteksi fork/scissors dari contoh ini. Langganan gratis memungkinkan untuk dua proyek Custom Vision.
Di situs web Custom Vision, navigasi ke Proyek dan pilih tempat sampah di bawah Proyek Baru Saya.
Langkah berikutnya
Sekarang Anda telah melakukan setiap langkah proses deteksi objek dalam kode. Sampel ini menjalankan perulangan pelatihan tunggal, tetapi sering kali Anda harus melatih dan menguji model Anda beberapa kali untuk membuatnya lebih akurat. Panduan berikut menangani klasifikasi gambar, tetapi prinsip-prinsipnya mirip dengan deteksi objek.
- Apa itu Custom Vision?
- Kode sumber untuk sampel ini dapat ditemukan di GitHub
Panduan ini menyediakan instruksi dan kode sampel untuk membantu Anda mulai menggunakan pustaka klien Visi Kustom untuk Node.js guna membangun model deteksi objek. Anda akan membuat proyek, menambahkan tag, melatih proyek, dan menggunakan URL titik akhir prediksi proyek untuk mengujinya secara terprogram. Gunakan contoh ini sebagai templat untuk membuat aplikasi pengenalan gambar Anda sendiri.
Catatan
Jika Anda ingin membangun dan melatih model deteksi objek tanpa menulis kode, lihat panduan berbasis browser.
Gunakan pustaka klien Custom Vision untuk .NET untuk:
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan menandai gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Dokumentasi referensi (pelatihan) (prediksi) | Paket (npm) (pelatihan) (prediksi) | Sampel
Prasyarat
- Langganan Azure - Buat langganan secara gratis
- Versi terbaru Node.js
- Setelah Anda memiliki langganan Azure, buat sumber daya Custom Vision di portal Azure untuk membuat sumber daya pelatihan dan prediksi.
- Anda dapat menggunakan tingkat harga gratis (
F0
) untuk percobaan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
- Anda dapat menggunakan tingkat harga gratis (
Membuat variabel lingkungan
Dalam contoh ini, Anda akan menulis kredensial Anda ke variabel lingkungan pada komputer lokal yang menjalankan aplikasi.
Buka portal Microsoft Azure. Jika sumber daya Custom Vision yang Anda buat di bagian Prasyarat berhasil disebarkan, pilih tombol Buka Sumber Daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya. Anda harus mendapatkan kunci untuk sumber daya pelatihan dan prediksi Anda, bersama dengan titik akhir API.
Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya prediksi di portal Azure, yang tercantum sebagai ID Sumber Daya.
Tip
Anda juga menggunakan https://www.customvision.ai/ untuk mendapatkan nilai-nilai ini. Setelah masuk, pilih ikon Pengaturan di kanan atas. Pada halaman Pengaturan , Anda dapat melihat semua kunci, ID sumber daya, dan titik akhir.
Untuk mengatur variabel lingkungan, buka jendela konsol dan ikuti instruksi untuk sistem operasi dan lingkungan pengembangan Anda.
- Untuk mengatur
VISION_TRAINING KEY
variabel lingkungan, gantiyour-training-key
dengan salah satu kunci untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_TRAINING_ENDPOINT
variabel lingkungan, gantiyour-training-endpoint
dengan titik akhir untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_PREDICTION_KEY
variabel lingkungan, gantiyour-prediction-key
dengan salah satu kunci untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_ENDPOINT
variabel lingkungan, gantiyour-prediction-endpoint
dengan titik akhir untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_RESOURCE_ID
variabel lingkungan, gantiyour-resource-id
dengan ID sumber daya untuk sumber daya prediksi Anda.
Penting
Jika Anda menggunakan kunci API, simpan dengan aman di tempat lain, seperti di Azure Key Vault. Jangan sertakan kunci API langsung dalam kode Anda, dan jangan pernah mempostingnya secara publik.
Untuk informasi selengkapnya tentang keamanan layanan AI, lihat Mengautentikasi permintaan ke layanan Azure AI.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id
Setelah menambahkan variabel lingkungan, Anda mungkin perlu memulai ulang program yang sedang berjalan yang akan membaca variabel lingkungan, termasuk jendela konsol.
Menyiapkan
Membuat aplikasi Node.js baru
Di jendela konsol (seperti cmd, PowerShell, atau Bash), buat direktori baru untuk aplikasi Anda, dan buka direktori tersebut.
mkdir myapp && cd myapp
Jalankan perintah npm init
untuk membuat aplikasi node dengan file package.json
.
npm init
Memasang pustaka klien
Untuk menulis aplikasi analisis gambar dengan Visi Kustom untuk Node.js, Anda memerlukan paket NPM Visi Kustom. Untuk menginstalnya, jalankan perintah berikut ini di PowerShell:
npm install @azure/cognitiveservices-customvision-training
npm install @azure/cognitiveservices-customvision-prediction
File package.json
aplikasi Anda akan diperbarui dengan dependensi.
Buat file bernama index.js
dan impor pustaka berikut ini:
const util = require('util');
const fs = require('fs');
const TrainingApi = require("@azure/cognitiveservices-customvision-training");
const PredictionApi = require("@azure/cognitiveservices-customvision-prediction");
const msRest = require("@azure/ms-rest-js");
Tip
Ingin menampilkan seluruh file kode mulai cepat sekaligus? Anda dapat menemukannya di GitHub, yang berisi contoh kode dalam mulai cepat ini.
Buat variabel untuk titik akhir dan kunci Azure sumber daya Anda.
// retrieve environment variables
const trainingKey = process.env["VISION_TRAINING_KEY"];
const trainingEndpoint = process.env["VISION_TRAINING_ENDPOINT"];
const predictionKey = process.env["VISION_PREDICTION_KEY"];
const predictionResourceId = process.env["VISION_PREDICTION_RESOURCE_ID"];
const predictionEndpoint = process.env["VISION_PREDICTION_ENDPOINT"];
Tambahkan juga bidang untuk nama proyek Anda dan parameter waktu habis untuk panggilan asinkron.
const publishIterationName = "detectModel";
const setTimeoutPromise = util.promisify(setTimeout);
Model objek
Nama | Deskripsi |
---|---|
TrainingAPIClient | Kelas ini menangani pembuatan, pelatihan, dan penerbitan model Anda. |
PredictionAPIClient | Kelas ini menangani kueri model Anda untuk prediksi deteksi objek. |
prediksi | Antarmuka ini mendefinisikan prediksi tunggal pada satu gambar. Ini termasuk properti untuk ID dan nama objek, serta skor keyakinan. |
Contoh kode
Cuplikan kode ini memperlihatkan kepada Anda cara melakukan tugas berikut dengan pustaka klien Visi Kustom untuk JavaScript:
- Autentikasi klien
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan memberi tag pada gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Mengautentikasi klien
Inisiasi objek klien dengan titik akhir dan kunci Anda. Buat objek ApiKeyCredentials dengan kunci Anda, dan gunakan dengan titik akhir Anda untuk membuat objek TrainingAPIClient dan PredictionAPIClient.
const credentials = new msRest.ApiKeyCredentials({ inHeader: { "Training-key": trainingKey } });
const trainer = new TrainingApi.TrainingAPIClient(credentials, trainingEndpoint);
const predictor_credentials = new msRest.ApiKeyCredentials({ inHeader: { "Prediction-key": predictionKey } });
const predictor = new PredictionApi.PredictionAPIClient(predictor_credentials, predictionEndpoint);
Menambahkan fungsi pembantu
Tambahkan fungsi berikut untuk membantu melakukan beberapa panggilan asinkron. Anda akan menggunakan ini nanti.
const credentials = new msRest.ApiKeyCredentials({ inHeader: { "Training-key": trainingKey } });
const trainer = new TrainingApi.TrainingAPIClient(credentials, trainingEndpoint);
const predictor_credentials = new msRest.ApiKeyCredentials({ inHeader: { "Prediction-key": predictionKey } });
const predictor = new PredictionApi.PredictionAPIClient(predictor_credentials, predictionEndpoint);
Membuat proyek Custom Vision baru
Mulai fungsi baru untuk berisi semua panggilan fungsi Visi Kustom Anda. Tambahkan kode berikut untuk membuat proyek layanan Visi Kustom baru.
(async () => {
console.log("Creating project...");
const domains = await trainer.getDomains()
const objDetectDomain = domains.find(domain => domain.type === "ObjectDetection");
const sampleProject = await trainer.createProject("Sample Obj Detection Project", { domainId: objDetectDomain.id });
Menambahkan tag ke proyek
Untuk membuat tag klasifikasi ke proyek Anda, tambahkan kode berikut ke fungsi Anda:
const forkTag = await trainer.createTag(sampleProject.id, "Fork");
const scissorsTag = await trainer.createTag(sampleProject.id, "Scissors");
Mengunggah dan menandai gambar
Pertama, unduh gambar sampel untuk proyek ini. Simpan konten folder gambar sampel ke perangkat lokal Anda.
Untuk menambahkan gambar sampel ke proyek, sisipkan kode berikut setelah pembuatan tag. Kode ini mengunggah setiap gambar dengan tag yang sesuai. Saat Anda memberi tag pada gambar dalam proyek deteksi objek, Anda perlu menentukan wilayah setiap objek yang diberi tag menggunakan koordinat yang dinormalisasi. Untuk tutorial ini, wilayah dikodekan secara permanen sejajar dengan kode. Wilayah menentukan kotak pembatas dalam koordinat yang dinormalisasi, dan koordinat diberikan dalam urutan: kiri, atas, lebar, tinggi. Anda dapat mengunggah hingga 64 gambar dalam satu batch.
const sampleDataRoot = "Images";
const forkImageRegions = {
"fork_1.jpg": [0.145833328, 0.3509314, 0.5894608, 0.238562092],
"fork_2.jpg": [0.294117659, 0.216944471, 0.534313738, 0.5980392],
"fork_3.jpg": [0.09191177, 0.0682516545, 0.757352948, 0.6143791],
"fork_4.jpg": [0.254901975, 0.185898721, 0.5232843, 0.594771266],
"fork_5.jpg": [0.2365196, 0.128709182, 0.5845588, 0.71405226],
"fork_6.jpg": [0.115196079, 0.133611143, 0.676470637, 0.6993464],
"fork_7.jpg": [0.164215669, 0.31008172, 0.767156839, 0.410130739],
"fork_8.jpg": [0.118872553, 0.318251669, 0.817401946, 0.225490168],
"fork_9.jpg": [0.18259804, 0.2136765, 0.6335784, 0.643790841],
"fork_10.jpg": [0.05269608, 0.282303959, 0.8088235, 0.452614367],
"fork_11.jpg": [0.05759804, 0.0894935, 0.9007353, 0.3251634],
"fork_12.jpg": [0.3345588, 0.07315363, 0.375, 0.9150327],
"fork_13.jpg": [0.269607842, 0.194068655, 0.4093137, 0.6732026],
"fork_14.jpg": [0.143382356, 0.218578458, 0.7977941, 0.295751631],
"fork_15.jpg": [0.19240196, 0.0633497, 0.5710784, 0.8398692],
"fork_16.jpg": [0.140931368, 0.480016381, 0.6838235, 0.240196079],
"fork_17.jpg": [0.305147052, 0.2512582, 0.4791667, 0.5408496],
"fork_18.jpg": [0.234068632, 0.445702642, 0.6127451, 0.344771236],
"fork_19.jpg": [0.219362751, 0.141781077, 0.5919118, 0.6683006],
"fork_20.jpg": [0.180147052, 0.239820287, 0.6887255, 0.235294119]
};
const scissorsImageRegions = {
"scissors_1.jpg": [0.4007353, 0.194068655, 0.259803921, 0.6617647],
"scissors_2.jpg": [0.426470578, 0.185898721, 0.172794119, 0.5539216],
"scissors_3.jpg": [0.289215684, 0.259428144, 0.403186262, 0.421568632],
"scissors_4.jpg": [0.343137264, 0.105833367, 0.332107842, 0.8055556],
"scissors_5.jpg": [0.3125, 0.09766343, 0.435049027, 0.71405226],
"scissors_6.jpg": [0.379901975, 0.24308826, 0.32107842, 0.5718954],
"scissors_7.jpg": [0.341911763, 0.20714055, 0.3137255, 0.6356209],
"scissors_8.jpg": [0.231617644, 0.08459154, 0.504901946, 0.8480392],
"scissors_9.jpg": [0.170343131, 0.332957536, 0.767156839, 0.403594762],
"scissors_10.jpg": [0.204656869, 0.120539248, 0.5245098, 0.743464053],
"scissors_11.jpg": [0.05514706, 0.159754932, 0.799019635, 0.730392158],
"scissors_12.jpg": [0.265931368, 0.169558853, 0.5061275, 0.606209159],
"scissors_13.jpg": [0.241421565, 0.184264734, 0.448529422, 0.6830065],
"scissors_14.jpg": [0.05759804, 0.05027781, 0.75, 0.882352948],
"scissors_15.jpg": [0.191176474, 0.169558853, 0.6936275, 0.6748366],
"scissors_16.jpg": [0.1004902, 0.279036, 0.6911765, 0.477124184],
"scissors_17.jpg": [0.2720588, 0.131977156, 0.4987745, 0.6911765],
"scissors_18.jpg": [0.180147052, 0.112369314, 0.6262255, 0.6666667],
"scissors_19.jpg": [0.333333343, 0.0274019931, 0.443627447, 0.852941155],
"scissors_20.jpg": [0.158088237, 0.04047389, 0.6691176, 0.843137264]
};
console.log("Adding images...");
let fileUploadPromises = [];
const forkDir = `${sampleDataRoot}/fork`;
const forkFiles = fs.readdirSync(forkDir);
await asyncForEach(forkFiles, async (file) => {
const region = { tagId: forkTag.id, left: forkImageRegions[file][0], top: forkImageRegions[file][1], width: forkImageRegions[file][2], height: forkImageRegions[file][3] };
const entry = { name: file, contents: fs.readFileSync(`${forkDir}/${file}`), regions: [region] };
const batch = { images: [entry] };
// Wait one second to accommodate rate limit.
await setTimeoutPromise(1000, null);
fileUploadPromises.push(trainer.createImagesFromFiles(sampleProject.id, batch));
});
const scissorsDir = `${sampleDataRoot}/scissors`;
const scissorsFiles = fs.readdirSync(scissorsDir);
await asyncForEach(scissorsFiles, async (file) => {
const region = { tagId: scissorsTag.id, left: scissorsImageRegions[file][0], top: scissorsImageRegions[file][1], width: scissorsImageRegions[file][2], height: scissorsImageRegions[file][3] };
const entry = { name: file, contents: fs.readFileSync(`${scissorsDir}/${file}`), regions: [region] };
const batch = { images: [entry] };
// Wait one second to accommodate rate limit.
await setTimeoutPromise(1000, null);
fileUploadPromises.push(trainer.createImagesFromFiles(sampleProject.id, batch));
});
await Promise.all(fileUploadPromises);
Penting
Anda harus mengubah jalur ke gambar (sampleDataRoot
) berdasarkan tempat Anda mengunduh repositori Sampel Python SDK layanan Azure AI.
Catatan
Jika Anda tidak memiliki utilitas klik-dan-seret untuk menandai koordinat wilayah, Anda dapat menggunakan UI web di Customvision.ai. Dalam contoh ini, koordinat sudah disediakan.
Melatih proyek
Kode ini membuat perulangan pertama model prediksi.
console.log("Training...");
let trainingIteration = await trainer.trainProject(sampleProject.id);
// Wait for training to complete
console.log("Training started...");
while (trainingIteration.status == "Training") {
console.log("Training status: " + trainingIteration.status);
// wait for ten seconds
await setTimeoutPromise(10000, null);
trainingIteration = await trainer.getIteration(sampleProject.id, trainingIteration.id)
}
console.log("Training status: " + trainingIteration.status);
Menerbitkan perulangan saat ini
Kode ini menerbitkan perulangan terlatih ke titik akhir prediksi. Nama yang diberikan pada perulangan yang dipublikasikan dapat digunakan untuk mengirim permintaan prediksi. Perulangan tidak tersedia di titik akhir prediksi hingga diterbitkan.
// Publish the iteration to the end point
await trainer.publishIteration(sampleProject.id, trainingIteration.id, publishIterationName, predictionResourceId);
Menguji titik akhir prediksi
Untuk mengirim gambar ke titik akhir prediksi dan mengambil prediksi, tambahkan kode berikut ke fungsi Anda.
const testFile = fs.readFileSync(`${sampleDataRoot}/test/test_image.jpg`);
const results = await predictor.detectImage(sampleProject.id, publishIterationName, testFile)
// Show results
console.log("Results:");
results.predictions.forEach(predictedResult => {
console.log(`\t ${predictedResult.tagName}: ${(predictedResult.probability * 100.0).toFixed(2)}% ${predictedResult.boundingBox.left},${predictedResult.boundingBox.top},${predictedResult.boundingBox.width},${predictedResult.boundingBox.height}`);
});
Kemudian, tutup fungsi Visi Kustom Anda lalu lakukan panggilan.
})()
Jalankan aplikasi
Jalankan aplikasi dengan perintah node
pada file mulai cepat Anda.
node index.js
Output aplikasi akan muncul di konsol. Kemudian Anda dapat memverifikasi bahwa gambar pengujian (ditemukan dalam <sampleDataRoot>/Test/) diberi tag dengan tepat dan bahwa wilayah deteksi sudah benar. Anda juga dapat kembali ke situs web Custom Vision dan melihat status terbaru proyek Anda yang baru saja dibuat.
Membersihkan sumber daya
Jika Anda ingin menerapkan proyek deteksi objek Anda sendiri (atau mencoba proyek klasifikasi gambar), hapus proyek deteksi fork/scissors dari contoh ini. Langganan gratis memungkinkan untuk dua proyek Custom Vision.
Di situs web Custom Vision, navigasi ke Proyek dan pilih tempat sampah di bawah Proyek Baru Saya.
Langkah berikutnya
Sekarang Anda telah melakukan setiap langkah proses deteksi objek dalam kode. Sampel ini menjalankan perulangan pelatihan tunggal, tetapi sering kali Anda harus melatih dan menguji model Anda beberapa kali untuk membuatnya lebih akurat. Panduan berikut menangani klasifikasi gambar, tetapi prinsip-prinsipnya mirip dengan deteksi objek.
- Apa itu Custom Vision?
- Kode sumber untuk sampel ini dapat ditemukan di GitHub
- Dokumentasi referensi SDK (pelatihan)
- Dokumentasi referensi SDK (prediksi)
Mulai menggunakan pustaka klien Custom Vision untuk Python. Ikuti langkah-langkah ini untuk menginstal paket dan mencoba contoh kode untuk mem-build model deteksi objek. Anda akan membuat proyek, menambahkan tag, melatih proyek, dan menggunakan URL titik akhir prediksi proyek untuk mengujinya secara terprogram. Gunakan contoh ini sebagai templat untuk membuat aplikasi pengenalan gambar Anda sendiri.
Catatan
Jika Anda ingin membangun dan melatih model deteksi objek tanpa menulis kode, lihat panduan berbasis browser.
Gunakan pustaka klien Custom Vision untuk Python untuk:
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan menandai gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Dokumentasi referensi | Kode sumber pustaka | Paket (PyPi) | Sampel
Prasyarat
- Langganan Azure - Buat langganan secara gratis
- Python 3.x
- Penginstalan Python Anda harus menyertakan pip. Anda dapat memeriksa apakah pip terinstal dengan menjalankan
pip --version
pada baris perintah. Dapatkan pip dengan menginstal versi terbaru Python.
- Penginstalan Python Anda harus menyertakan pip. Anda dapat memeriksa apakah pip terinstal dengan menjalankan
- Setelah Anda memiliki langganan Azure, buat sumber daya Custom Vision di portal Azure untuk membuat sumber daya pelatihan dan prediksi.
- Anda dapat menggunakan tingkat harga gratis (
F0
) untuk percobaan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
- Anda dapat menggunakan tingkat harga gratis (
Membuat variabel lingkungan
Dalam contoh ini, Anda akan menulis kredensial Anda ke variabel lingkungan pada komputer lokal yang menjalankan aplikasi.
Buka portal Microsoft Azure. Jika sumber daya Custom Vision yang Anda buat di bagian Prasyarat berhasil disebarkan, pilih tombol Buka Sumber Daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya. Anda harus mendapatkan kunci untuk sumber daya pelatihan dan prediksi Anda, bersama dengan titik akhir API.
Anda dapat menemukan ID sumber daya prediksi pada tab Properti sumber daya prediksi di portal Azure, yang tercantum sebagai ID Sumber Daya.
Tip
Anda juga menggunakan https://www.customvision.ai/ untuk mendapatkan nilai-nilai ini. Setelah masuk, pilih ikon Pengaturan di kanan atas. Pada halaman Pengaturan , Anda dapat melihat semua kunci, ID sumber daya, dan titik akhir.
Untuk mengatur variabel lingkungan, buka jendela konsol dan ikuti instruksi untuk sistem operasi dan lingkungan pengembangan Anda.
- Untuk mengatur
VISION_TRAINING KEY
variabel lingkungan, gantiyour-training-key
dengan salah satu kunci untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_TRAINING_ENDPOINT
variabel lingkungan, gantiyour-training-endpoint
dengan titik akhir untuk sumber daya pelatihan Anda. - Untuk mengatur
VISION_PREDICTION_KEY
variabel lingkungan, gantiyour-prediction-key
dengan salah satu kunci untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_ENDPOINT
variabel lingkungan, gantiyour-prediction-endpoint
dengan titik akhir untuk sumber daya prediksi Anda. - Untuk mengatur
VISION_PREDICTION_RESOURCE_ID
variabel lingkungan, gantiyour-resource-id
dengan ID sumber daya untuk sumber daya prediksi Anda.
Penting
Jika Anda menggunakan kunci API, simpan dengan aman di tempat lain, seperti di Azure Key Vault. Jangan sertakan kunci API langsung dalam kode Anda, dan jangan pernah mempostingnya secara publik.
Untuk informasi selengkapnya tentang keamanan layanan AI, lihat Mengautentikasi permintaan ke layanan Azure AI.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id
Setelah menambahkan variabel lingkungan, Anda mungkin perlu memulai ulang program yang sedang berjalan yang akan membaca variabel lingkungan, termasuk jendela konsol.
Menyiapkan
Memasang pustaka klien
Untuk menulis aplikasi analisis gambar dengan Custom Vision untuk Python, Anda memerlukan pustaka klien Custom Vision. Setelah menginstal Python, jalankan perintah berikut di PowerShell atau jendela konsol:
pip install azure-cognitiveservices-vision-customvision
Membuat aplikasi Python baru
Membuat file Python baru dan mengimpor pustaka berikut.
from azure.cognitiveservices.vision.customvision.training import CustomVisionTrainingClient
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
from azure.cognitiveservices.vision.customvision.training.models import ImageFileCreateBatch, ImageFileCreateEntry, Region
from msrest.authentication import ApiKeyCredentials
import os, time, uuid
Tip
Ingin menampilkan seluruh file kode mulai cepat sekaligus? Anda dapat menemukannya di GitHub, yang berisi contoh kode dalam mulai cepat ini.
Buat variabel untuk titik akhir dan kunci Azure sumber daya Anda.
# Replace with valid values
ENDPOINT = os.environ["VISION_TRAINING_ENDPOINT"]
training_key = os.environ["VISION_TRAINING_KEY"]
prediction_key = os.environ["VISION_PREDICTION_KEY"]
prediction_resource_id = os.environ["VISION_PREDICTION_RESOURCE_ID"]
Model objek
Nama | Deskripsi |
---|---|
CustomVisionTrainingClient | Kelas ini menangani pembuatan, pelatihan, dan penerbitan model Anda. |
CustomVisionPredictionClient | Kelas ini menangani kueri model Anda untuk prediksi deteksi objek. |
ImagePrediction | Kelas ini menentukan satu prediksi objek pada satu gambar. Ini mencakup properti untuk ID dan nama objek, lokasi kotak batas objek, serta skor keyakinan. |
Contoh kode
Cuplikan kode ini menunjukkan cara melakukan hal berikut ini dengan pustaka klien Custom Vision untuk Python:
- Autentikasi klien
- Membuat proyek Custom Vision baru
- Menambahkan tag ke proyek
- Mengunggah dan memberi tag pada gambar
- Melatih proyek
- Menerbitkan perulangan saat ini
- Menguji titik akhir prediksi
Mengautentikasi klien
Beri contoh klien pelatihan dan prediksi dengan titik akhir dan kunci Anda. Buat objek ApiKeyServiceClientCredentials dengan kunci Anda dan gunakan dengan titik akhir Anda untuk membuat objek CustomVisionTrainingClient dan CustomVisionPredictionClient.
credentials = ApiKeyCredentials(in_headers={"Training-key": training_key})
trainer = CustomVisionTrainingClient(ENDPOINT, credentials)
prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})
predictor = CustomVisionPredictionClient(ENDPOINT, prediction_credentials)
Membuat proyek Custom Vision baru
Tambahkan kode berikut ke skrip Anda untuk membuat proyek layanan Custom Vision baru.
Lihat metode create_project untuk menentukan opsi lain saat Anda membuat proyek (yang dijelaskan dalam panduan portal web Membuat detektor).
publish_iteration_name = "detectModel"
# Find the object detection domain
obj_detection_domain = next(domain for domain in trainer.get_domains() if domain.type == "ObjectDetection" and domain.name == "General")
# Create a new project
print ("Creating project...")
# Use uuid to avoid project name collisions.
project = trainer.create_project(str(uuid.uuid4()), domain_id=obj_detection_domain.id)
Menambahkan tag ke proyek
Untuk membuat tag objek di project Anda, tambahkan kode berikut:
# Make two tags in the new project
fork_tag = trainer.create_tag(project.id, "fork")
scissors_tag = trainer.create_tag(project.id, "scissors")
Mengunggah dan menandai gambar
Pertama, unduh gambar sampel untuk proyek ini. Simpan konten folder gambar sampel ke perangkat lokal Anda.
Saat Anda memberi tag pada gambar dalam proyek deteksi objek, Anda perlu menentukan wilayah setiap objek yang diberi tag menggunakan koordinat yang dinormalisasi. Kode berikut mengaitkan setiap gambar sampel dengan wilayahnya yang diberi tag. Wilayah menentukan kotak pembatas dalam koordinat yang dinormalisasi, dan koordinat diberikan dalam urutan: kiri, atas, lebar, tinggi.
fork_image_regions = {
"fork_1": [ 0.145833328, 0.3509314, 0.5894608, 0.238562092 ],
"fork_2": [ 0.294117659, 0.216944471, 0.534313738, 0.5980392 ],
"fork_3": [ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 ],
"fork_4": [ 0.254901975, 0.185898721, 0.5232843, 0.594771266 ],
"fork_5": [ 0.2365196, 0.128709182, 0.5845588, 0.71405226 ],
"fork_6": [ 0.115196079, 0.133611143, 0.676470637, 0.6993464 ],
"fork_7": [ 0.164215669, 0.31008172, 0.767156839, 0.410130739 ],
"fork_8": [ 0.118872553, 0.318251669, 0.817401946, 0.225490168 ],
"fork_9": [ 0.18259804, 0.2136765, 0.6335784, 0.643790841 ],
"fork_10": [ 0.05269608, 0.282303959, 0.8088235, 0.452614367 ],
"fork_11": [ 0.05759804, 0.0894935, 0.9007353, 0.3251634 ],
"fork_12": [ 0.3345588, 0.07315363, 0.375, 0.9150327 ],
"fork_13": [ 0.269607842, 0.194068655, 0.4093137, 0.6732026 ],
"fork_14": [ 0.143382356, 0.218578458, 0.7977941, 0.295751631 ],
"fork_15": [ 0.19240196, 0.0633497, 0.5710784, 0.8398692 ],
"fork_16": [ 0.140931368, 0.480016381, 0.6838235, 0.240196079 ],
"fork_17": [ 0.305147052, 0.2512582, 0.4791667, 0.5408496 ],
"fork_18": [ 0.234068632, 0.445702642, 0.6127451, 0.344771236 ],
"fork_19": [ 0.219362751, 0.141781077, 0.5919118, 0.6683006 ],
"fork_20": [ 0.180147052, 0.239820287, 0.6887255, 0.235294119 ]
}
scissors_image_regions = {
"scissors_1": [ 0.4007353, 0.194068655, 0.259803921, 0.6617647 ],
"scissors_2": [ 0.426470578, 0.185898721, 0.172794119, 0.5539216 ],
"scissors_3": [ 0.289215684, 0.259428144, 0.403186262, 0.421568632 ],
"scissors_4": [ 0.343137264, 0.105833367, 0.332107842, 0.8055556 ],
"scissors_5": [ 0.3125, 0.09766343, 0.435049027, 0.71405226 ],
"scissors_6": [ 0.379901975, 0.24308826, 0.32107842, 0.5718954 ],
"scissors_7": [ 0.341911763, 0.20714055, 0.3137255, 0.6356209 ],
"scissors_8": [ 0.231617644, 0.08459154, 0.504901946, 0.8480392 ],
"scissors_9": [ 0.170343131, 0.332957536, 0.767156839, 0.403594762 ],
"scissors_10": [ 0.204656869, 0.120539248, 0.5245098, 0.743464053 ],
"scissors_11": [ 0.05514706, 0.159754932, 0.799019635, 0.730392158 ],
"scissors_12": [ 0.265931368, 0.169558853, 0.5061275, 0.606209159 ],
"scissors_13": [ 0.241421565, 0.184264734, 0.448529422, 0.6830065 ],
"scissors_14": [ 0.05759804, 0.05027781, 0.75, 0.882352948 ],
"scissors_15": [ 0.191176474, 0.169558853, 0.6936275, 0.6748366 ],
"scissors_16": [ 0.1004902, 0.279036, 0.6911765, 0.477124184 ],
"scissors_17": [ 0.2720588, 0.131977156, 0.4987745, 0.6911765 ],
"scissors_18": [ 0.180147052, 0.112369314, 0.6262255, 0.6666667 ],
"scissors_19": [ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 ],
"scissors_20": [ 0.158088237, 0.04047389, 0.6691176, 0.843137264 ]
}
Catatan
Jika Anda tidak memiliki utilitas klik-dan-seret untuk menandai koordinat wilayah, Anda dapat menggunakan UI web di Customvision.ai. Dalam contoh ini, koordinat sudah disediakan.
Kemudian, gunakan peta asosiasi ini untuk mengunggah setiap gambar sampel dengan koordinat wilayahnya (Anda dapat mengunggah hingga 64 gambar dalam satu batch). Tambahkan kode berikut.
base_image_location = os.path.join (os.path.dirname(__file__), "Images")
# Go through the data table above and create the images
print ("Adding images...")
tagged_images_with_regions = []
for file_name in fork_image_regions.keys():
x,y,w,h = fork_image_regions[file_name]
regions = [ Region(tag_id=fork_tag.id, left=x,top=y,width=w,height=h) ]
with open(os.path.join (base_image_location, "fork", file_name + ".jpg"), mode="rb") as image_contents:
tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))
for file_name in scissors_image_regions.keys():
x,y,w,h = scissors_image_regions[file_name]
regions = [ Region(tag_id=scissors_tag.id, left=x,top=y,width=w,height=h) ]
with open(os.path.join (base_image_location, "scissors", file_name + ".jpg"), mode="rb") as image_contents:
tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))
upload_result = trainer.create_images_from_files(project.id, ImageFileCreateBatch(images=tagged_images_with_regions))
if not upload_result.is_batch_successful:
print("Image batch upload failed.")
for image in upload_result.images:
print("Image status: ", image.status)
exit(-1)
Catatan
Anda harus mengubah jalur ke gambar berdasarkan tempat Anda mengunduh repositori Sampel Python SDK layanan Azure AI sebelumnya.
Melatih proyek
Kode ini membuat perulangan pertama model prediksi.
print ("Training...")
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
iteration = trainer.get_iteration(project.id, iteration.id)
print ("Training status: " + iteration.status)
time.sleep(1)
Tip
Berlatih dengan tag yang dipilih
Secara opsional, Anda dapat berlatih hanya dengan subkumpulan tag yang Anda terapkan. Anda mungkin ingin melakukannya jika belum cukup menerapkan tag tertentu, tetapi Anda memiliki cukup banyak tag lain. Dalam panggilan train_project, atur parameter selected_tags ke daftar string ID tag yang ingin Anda gunakan. Model akan dilatih untuk hanya mengenali tag dalam daftar itu.
Menerbitkan perulangan saat ini
Perulangan tidak tersedia di titik akhir prediksi hingga diterbitkan. Kode berikut membuat perulangan model saat ini tersedia untuk kueri.
# The iteration is now trained. Publish it to the project endpoint
trainer.publish_iteration(project.id, iteration.id, publish_iteration_name, prediction_resource_id)
print ("Done!")
Menguji titik akhir prediksi
Untuk mengirim gambar ke titik akhir prediksi dan mengambil prediksi, tambahkan kode berikut ke akhir file:
# Now there is a trained endpoint that can be used to make a prediction
# Open the sample image and get back the prediction results.
with open(os.path.join (base_image_location, "test", "test_image.jpg"), mode="rb") as test_data:
results = predictor.detect_image(project.id, publish_iteration_name, test_data)
# Display the results.
for prediction in results.predictions:
print("\t" + prediction.tag_name + ": {0:.2f}% bbox.left = {1:.2f}, bbox.top = {2:.2f}, bbox.width = {3:.2f}, bbox.height = {4:.2f}".format(prediction.probability * 100, prediction.bounding_box.left, prediction.bounding_box.top, prediction.bounding_box.width, prediction.bounding_box.height))
Jalankan aplikasi
Jalankan CustomVisionQuickstart.py.
python CustomVisionQuickstart.py
Output aplikasi akan muncul di konsol. Kemudian, Anda dapat memverifikasi bahwa gambar pengujian (yang ditemukan di <base_image_location>/images/Test) ditandai dengan tepat dan bahwa wilayah deteksi sudah benar. Anda juga dapat kembali ke situs web Custom Vision dan melihat status terbaru proyek Anda yang baru saja dibuat.
Membersihkan sumber daya
Jika Anda ingin menerapkan proyek deteksi objek Anda sendiri (atau mencoba proyek klasifikasi gambar), hapus proyek deteksi fork/scissors dari contoh ini. Langganan gratis memungkinkan untuk dua proyek Custom Vision.
Di situs web Custom Vision, navigasi ke Proyek dan pilih tempat sampah di bawah Proyek Baru Saya.
Langkah berikutnya
Sekarang Anda telah melakukan setiap langkah proses deteksi objek dalam kode. Sampel ini menjalankan perulangan pelatihan tunggal, tetapi sering kali Anda harus melatih dan menguji model Anda beberapa kali untuk membuatnya lebih akurat. Panduan berikut menangani klasifikasi gambar, tetapi prinsip-prinsipnya mirip dengan deteksi objek.
- Apa itu Custom Vision?
- Kode sumber untuk sampel ini dapat ditemukan di GitHub
- Dokumentasi referensi SDK