1. Zanim zaczniesz
MediaPipe Solutions umożliwia stosowanie w aplikacjach rozwiązań wykorzystujących systemy uczące się. Udostępnia ona ramy, które umożliwiają konfigurowanie gotowych przepływów przetwarzania, które dostarczają użytkownikom natychmiastowych, atrakcyjnych i przydatnych wyników. Możesz nawet dostosować te rozwiązania za pomocą Model Makera, aby zaktualizować modele domyślne.
Wykrywanie obiektów to jedno z kilku zadań dotyczących widzenia AI, które oferuje MediaPipe Solutions. MediaPipe Tasks jest dostępny w wersji na Androida, w Pythonie i w internecie.
W tym laboratorium kodu dodasz do aplikacji internetowej wykrywanie obiektów, aby wykrywać psy na zdjęciach i w filmach z kamery internetowej.
Czego się nauczysz
- Jak uwzględnić zadanie wykrywania obiektów w aplikacji internetowej za pomocą MediaPipe Tasks.
Co utworzysz
- Aplikacja internetowa, która wykrywa obecność psów. Możesz też dostosować model do wykrywania wybranej klasy obiektów za pomocą MediaPipe Model Maker.
Czego potrzebujesz
- Konto CodePen
- Urządzenie z przeglądarką
- podstawy JavaScriptu, CSS i HTML;
2. Konfiguracja
Ten warsztat programistyczny uruchamia kod w CodePen, czyli środowisku programistycznym, które umożliwia pisanie kodu w przeglądarce i sprawdzanie wyników w miarę tworzenia.
Aby przeprowadzić konfigurację, wykonaj te czynności:
- Na koncie CodePen otwórz CodePen. Użyj tego kodu jako podstawy do utworzenia własnego wykrywacza obiektów.
- W dolnej części CodePen w menu nawigacyjnym kliknij Fork (Fork), aby utworzyć kopię kodu startowego.
- Na karcie JS kliknij strzałkę i wybierz Maksymalizacja edytora JavaScript. W tym ćwiczeniu możesz edytować tylko kod na karcie JS, więc nie musisz wyświetlać kart HTML ani CSS.
Sprawdzanie aplikacji inicjującej
- W panelu podglądu zobaczysz 2 zdjęcia psów i opcję włączenia kamery internetowej. Model, którego używasz w tym samouczku, został wytrenowany na 3 psach widocznych na 2 obrazach.
- Na karcie JS widać, że w kodzie znajduje się kilka komentarzy. Na przykład w wierszu 15 możesz znaleźć taki komentarz:
// Import the required package.
Te komentarze wskazują, gdzie należy wstawić fragmenty kodu.
3. Zaimportuj pakiet MediaPipe tasks-vision i dodaj wymagane zmienne
- Na karcie JS zaimportuj pakiet MediaPipe
tasks-vision
:
// Import the required package.
import { ObjectDetector, FilesetResolver, Detection } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@latest";
Ten kod używa sieci dostarczania treści (CDN) Skypack do importowania pakietu. Więcej informacji o korzystaniu z Skypack w połączeniu z CodePen znajdziesz w artykule Skypack + CodePen.
W swoich projektach możesz używać Node.js z npm lub wybranego menedżera pakietów albo CDN. Więcej informacji o wymaganym pakiecie, który należy zainstalować, znajdziesz w artykule Pakiety JavaScript.
- Zadeklaruj zmienne dla detektora obiektów i trybu działania:
// Create required variables.
let objectDetector = null;
let runningMode = "IMAGE";
Zmienna runningMode
to ciąg znaków, który ma wartość "IMAGE"
, gdy wykryjesz obiekty na zdjęciach, lub wartość "VIDEO"
, gdy wykryjesz obiekty w filmie.
4. Inicjalizacja detektora obiektów
- Aby zainicjować detektor obiektów, dodaj ten kod po odpowiednim komentarzu na karcie JS:
// Initialize the object detector.
async function initializeObjectDetector() {
const visionFilesetResolver = await FilesetResolver.forVisionTasks(
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
);
objectDetector = await ObjectDetector.createFromOptions(visionFilesetResolver, {
baseOptions: {
modelAssetPath: "https://storage.googleapis.com/mediapipe-assets/dogs.tflite"
},
scoreThreshold: 0.3,
runningMode: runningMode
});
}
initializeObjectDetector();
Metoda FilesetResolver.forVisionTasks()
określa lokalizację binarnego pliku WebAssembly (Wasm) dla zadania.
Metoda ObjectDetector.createFromOptions()
tworzy instancję detektora obiektów. Musisz podać ścieżkę do modelu używanego do wykrywania. W tym przypadku model wykrywania psów jest hostowany w Cloud Storage.
Właściwość scoreThreshold
ma wartość 0.3
. Oznacza to, że model zwraca wyniki dla każdego wykrytego obiektu z poziomem ufności co najmniej 30%. Możesz dostosować ten próg do potrzeb swojej aplikacji.
Właściwość runningMode
jest ustawiana podczas inicjowania obiektu ObjectDetector
. W razie potrzeby możesz później zmienić tę i inne opcje.
5. Przeprowadzanie prognoz na obrazach
- Aby przeprowadzić przewidywania na podstawie obrazów, otwórz funkcję
handleClick()
i dodaj do jej treści ten kod:
// Verify object detector is initialized and choose the correct running mode.
if (!objectDetector) {
alert("Object Detector still loading. Please try again");
return;
}
if (runningMode === "VIDEO") {
runningMode = "IMAGE";
await objectDetector.setOptions({ runningMode: runningMode });
}
Ten kod określa, czy detektor obiektów jest zainicjowany, i zapewnia, że tryb działania jest ustawiony dla obrazów.
Wykrywanie obiektów
- Aby wykrywać obiekty na obrazach, dodaj do funkcji
handleClick()
ten kod:
// Run object detection.
const detections = objectDetector.detect(event.target);
Ten fragment kodu zawiera przykład danych wyjściowych z tego zadania:
ObjectDetectionResult:
Detection #0:
Box: (x: 355, y: 133, w: 190, h: 206)
Categories:
index : 17
score : 0.73828
class name : aci
Detection #1:
Box: (x: 103, y: 15, w: 138, h: 369)
Categories:
index : 17
score : 0.73047
class name : tikka
Przetwarzanie i wyświetlanie prognoz
- Na końcu ciała funkcji
handleClick()
wywołaj funkcjędisplayImageDetections()
:
// Call the displayImageDetections() function.
displayImageDetections(detections, event.target);
- Aby wyświetlić wyniki wykrywania obiektów, dodaj do treści funkcji
displayImageDetections()
ten kod:
// Display object detection results.
const ratio = resultElement.height / resultElement.naturalHeight;
for (const detection of result.detections) {
// Description text
const p = document.createElement("p");
p.setAttribute("class", "info");
p.innerText =
detection.categories[0].categoryName +
" - with " +
Math.round(parseFloat(detection.categories[0].score) * 100) +
"% confidence.";
// Positioned at the top-left of the bounding box.
// Height is that of the text.
// Width subtracts text padding in CSS so that it fits perfectly.
p.style =
"left: " +
detection.boundingBox.originX * ratio +
"px;" +
"top: " +
detection.boundingBox.originY * ratio +
"px; " +
"width: " +
(detection.boundingBox.width * ratio - 10) +
"px;";
const highlighter = document.createElement("div");
highlighter.setAttribute("class", "highlighter");
highlighter.style =
"left: " +
detection.boundingBox.originX * ratio +
"px;" +
"top: " +
detection.boundingBox.originY * ratio +
"px;" +
"width: " +
detection.boundingBox.width * ratio +
"px;" +
"height: " +
detection.boundingBox.height * ratio +
"px;";
resultElement.parentNode.appendChild(highlighter);
resultElement.parentNode.appendChild(p);
}
Ta funkcja wyświetla ramki wokół obiektów wykrytych na obrazach. Usuwa wcześniejsze wyróżnienia, a następnie tworzy i wyświetla tagi <p>
, aby wyróżnić każdy wykryty obiekt.
Testowanie aplikacji
Gdy wprowadzisz zmiany w kodzie w CodePen, po zapisaniu panel podglądu zostanie automatycznie odświeżony. Jeśli automatyczne zapisywanie jest włączone, aplikacja prawdopodobnie została już odświeżona, ale warto ją odświeżyć jeszcze raz.
Aby przetestować aplikację:
- W okienku podglądu kliknij po kolei wszystkie obrazy, aby wyświetlić prognozy. Pole ograniczające zawiera nazwę psa i poziom ufności modelu.
- Jeśli nie ma ramki, otwórz Narzędzia deweloperskie w Chrome, a potem sprawdź panel Konsola pod kątem błędów. Możesz też sprawdzić poprzednie kroki, aby upewnić się, że niczego nie pominięto.
6. Wykonywanie prognoz na podstawie obrazu z kamery internetowej
Wykrywanie obiektów
- Aby wykrywać obiekty na bieżąco w filmie z kamery internetowej, otwórz funkcję
predictWebcam()
i dodaj do niej ten kod:
// Run video object detection.
// If image mode is initialized, create a classifier with video runningMode.
if (runningMode === "IMAGE") {
runningMode = "VIDEO";
await objectDetector.setOptions({ runningMode: runningMode });
}
let nowInMs = performance.now();
// Detect objects with the detectForVideo() method.
const result = await objectDetector.detectForVideo(video, nowInMs);
displayVideoDetections(result.detections);
Wykrywanie obiektów w filmie wykorzystuje te same metody niezależnie od tego, czy wykonujesz wnioskowanie na danych strumieniowych, czy na całym filmie. Metoda detectForVideo()
jest podobna do metody detect()
używanej w przypadku zdjęć, ale zawiera dodatkowy parametr dla sygnatury czasowej powiązanej z bieżącą ramką. Funkcja wykonuje wykrywanie na żywo, więc jako sygnatury czasowej używasz bieżącego czasu.
Przetwarzanie i wyświetlanie prognoz
- Aby przetworzyć i wyświetlić wyniki wykrywania, otwórz funkcję
displayVideoDetections()
i dodaj do niej ten kod:
// Display video object detection results.
for (let child of children) {
liveView.removeChild(child);
}
children.splice(0);
// Iterate through predictions and draw them to the live view.
for (const detection of result.detections) {
const p = document.createElement("p");
p.innerText =
detection.categories[0].categoryName +
" - with " +
Math.round(parseFloat(detection.categories[0].score) * 100) +
"% confidence.";
p.style =
"left: " +
(video.offsetWidth -
detection.boundingBox.width -
detection.boundingBox.originX) +
"px;" +
"top: " +
detection.boundingBox.originY +
"px; " +
"width: " +
(detection.boundingBox.width - 10) +
"px;";
const highlighter = document.createElement("div");
highlighter.setAttribute("class", "highlighter");
highlighter.style =
"left: " +
(video.offsetWidth -
detection.boundingBox.width -
detection.boundingBox.originX) +
"px;" +
"top: " +
detection.boundingBox.originY +
"px;" +
"width: " +
(detection.boundingBox.width - 10) +
"px;" +
"height: " +
detection.boundingBox.height +
"px;";
liveView.appendChild(highlighter);
liveView.appendChild(p);
// Store drawn objects in memory so that they're queued to delete at next call.
children.push(highlighter);
children.push(p);
}
}
Ten kod usuwa wcześniejsze wyróżnienia, a następnie tworzy i wyświetla tagi <p>
, aby wyróżnić każdy wykryty obiekt.
Testowanie aplikacji
Aby przetestować wykrywanie obiektów na żywo, warto mieć obraz jednego z psów, na których model został wytrenowany.
Aby przetestować aplikację:
- Pobierz na telefon jedno ze zdjęć psa.
- W okienku podglądu kliknij Włącz kamerę.
- Jeśli przeglądarka wyświetli okno z prośbą o dostęp do kamery internetowej, przyznaj go.
- Trzymaj zdjęcie psa na telefonie przed kamerą internetową. Boks ograniczający zawiera nazwę psa i poziom ufności modelu.
- Jeśli nie ma ramki, otwórz Narzędzia deweloperskie w Chrome, a potem sprawdź panel Konsola pod kątem błędów. Możesz też sprawdzić poprzednie kroki, aby upewnić się, że niczego nie pominięto.
7. Gratulacje
Gratulacje! Utworzyłeś(-aś) aplikację internetową, która wykrywa obiekty na obrazach. Więcej informacji znajdziesz w gotowej wersji aplikacji na CodePen.