1. Trước khi bắt đầu
MediaPipe Solutions giúp bạn áp dụng các giải pháp học máy (ML) cho các ứng dụng của mình. Thư viện này cung cấp một khung cho phép bạn định cấu hình các quy trình xử lý được tạo sẵn để cung cấp đầu ra tức thì, hấp dẫn và hữu ích cho người dùng. Bạn thậm chí có thể tuỳ chỉnh các giải pháp này bằng Model Maker để cập nhật các mô hình mặc định.
Phát hiện đối tượng là một trong nhiều nhiệm vụ liên quan đến thị giác học máy mà MediaPipe Solutions cung cấp. MediaPipe Tasks hỗ trợ Android, Python và web.
Trong lớp học lập trình này, bạn sẽ thêm tính năng phát hiện đối tượng vào một ứng dụng web để phát hiện chó trong hình ảnh và video webcam trực tiếp.
Kiến thức bạn sẽ học được
- Cách kết hợp nhiệm vụ phát hiện đối tượng trong ứng dụng web với MediaPipe Tasks.
Sản phẩm bạn sẽ tạo ra
- Ứng dụng web phát hiện sự hiện diện của chó. Bạn cũng có thể tuỳ chỉnh mô hình để phát hiện một lớp đối tượng mà bạn chọn bằng MediaPipe Model Maker.
Bạn cần có
- Tài khoản CodePen
- Một thiết bị có trình duyệt web
- Kiến thức cơ bản về JavaScript, CSS và HTML
2. Bắt đầu thiết lập
Lớp học lập trình này chạy mã của bạn trong CodePen,một môi trường phát triển xã hội cho phép bạn viết mã trong trình duyệt và kiểm tra kết quả khi bạn tạo bản dựng.
Để thiết lập, hãy làm theo các bước sau:
- Trong tài khoản CodePen của bạn, hãy chuyển đến CodePen này. Bạn dùng mã này làm cơ sở để tạo trình phát hiện vật thể của riêng mình.
- Ở cuối CodePen trong trình đơn điều hướng, hãy nhấp vào Nĩa để tạo bản sao của mã khởi đầu.
- Trong thẻ JS, hãy nhấp vào mũi tên mở rộng
, sau đó chọn Tối đa hoá trình chỉnh sửa JavaScript. Bạn chỉ chỉnh sửa công việc trong thẻ JS của lớp học lập trình này, vì vậy, bạn không cần phải xem các thẻ HTML hoặc CSS.
Xem xét ứng dụng khởi đầu
- Trong ngăn xem trước, hãy chú ý rằng có hai hình ảnh những chú chó và một tuỳ chọn chạy webcam của bạn. Mô hình mà bạn dùng trong hướng dẫn này đã được huấn luyện dựa trên 3 chú chó xuất hiện trong 2 hình ảnh.
- Trong thẻ JS, hãy lưu ý rằng có một số nhận xét xuyên suốt mã. Ví dụ: bạn có thể tìm thấy nhận xét sau trên dòng 15:
// Import the required package.
Các nhận xét này cho biết vị trí bạn cần chèn đoạn mã.
3. Nhập gói MediaPipe Tasks-vision và thêm các biến bắt buộc
- Trong thẻ JS, hãy nhập gói MediaPipe
tasks-vision
:
// Import the required package.
import { ObjectDetector, FilesetResolver, Detection } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@latest";
Mã này sử dụng mạng phân phối nội dung (CDN) Skypack để nhập gói. Để biết thêm thông tin về cách sử dụng Skypack với CodePen, hãy xem Skypack + CodePen.
Trong các dự án của mình, bạn có thể sử dụng Node.js với npm hoặc trình quản lý gói hay CDN mà bạn chọn. Để biết thêm thông tin về gói bắt buộc mà bạn cần cài đặt, hãy xem gói JavaScript.
- Khai báo các biến cho trình phát hiện đối tượng và chế độ chạy:
// Create required variables.
let objectDetector = null;
let runningMode = "IMAGE";
Biến runningMode
là một chuỗi được đặt thành giá trị "IMAGE"
khi bạn phát hiện các đối tượng trong hình ảnh hoặc giá trị "VIDEO"
khi bạn phát hiện các đối tượng trong video.
4. Khởi chạy trình phát hiện đối tượng
- Để khởi chạy trình phát hiện đối tượng, hãy thêm mã sau vào sau nhận xét liên quan trong thẻ 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();
Phương thức FilesetResolver.forVisionTasks()
chỉ định vị trí của tệp nhị phân WebAssembly (Wasm) cho tác vụ.
Phương thức ObjectDetector.createFromOptions()
sẽ tạo thực thể cho trình phát hiện đối tượng. Bạn phải cung cấp đường dẫn đến mô hình được dùng để phát hiện. Trong trường hợp này, mô hình phát hiện chó được lưu trữ trên Cloud Storage.
Thuộc tính scoreThreshold
được đặt thành giá trị 0.3
. Điều này có nghĩa là mô hình sẽ trả về kết quả cho mọi đối tượng được phát hiện có mức độ tin cậy từ 30% trở lên. Bạn có thể điều chỉnh ngưỡng này cho phù hợp với nhu cầu của ứng dụng.
Thuộc tính runningMode
được đặt khi khởi động đối tượng ObjectDetector
. Sau này, bạn có thể thay đổi lựa chọn này và các lựa chọn khác nếu cần.
5. Chạy dự đoán trên hình ảnh
- Để chạy dự đoán trên hình ảnh, hãy chuyển đến hàm
handleClick()
rồi thêm mã sau vào phần nội dung của hàm:
// 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 });
}
Mã này xác định xem trình phát hiện đối tượng có được khởi chạy hay không và đảm bảo rằng chế độ đang chạy được đặt cho hình ảnh.
Phát hiện đối tượng
- Để phát hiện đối tượng trong hình ảnh, hãy thêm mã sau vào phần nội dung của hàm
handleClick()
:
// Run object detection.
const detections = objectDetector.detect(event.target);
Đoạn mã sau đây cho thấy một ví dụ về dữ liệu đầu ra của tác vụ này:
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
Quy trình và hiển thị nội dung gợi ý
- Ở cuối phần nội dung của hàm
handleClick()
, hãy gọi hàmdisplayImageDetections()
:
// Call the displayImageDetections() function.
displayImageDetections(detections, event.target);
- Trong phần nội dung của hàm
displayImageDetections()
, hãy thêm mã sau để hiển thị kết quả phát hiện vật thể:
// 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);
}
Hàm này cho thấy các hộp giới hạn trên các đối tượng phát hiện được trong hình ảnh. Thao tác này sẽ xoá mọi đối tượng được đánh dấu trước đó, sau đó tạo và hiển thị các thẻ <p>
để đánh dấu từng đối tượng được phát hiện.
Kiểm thử ứng dụng
Khi bạn thay đổi mã trong CodePen, ngăn xem trước sẽ tự động làm mới sau khi lưu. Nếu tính năng lưu tự động được bật, ứng dụng của bạn có thể đã được làm mới, nhưng bạn nên làm mới lại.
Để kiểm thử ứng dụng, hãy làm theo các bước sau:
- Trong ngăn xem trước, hãy nhấp vào từng hình ảnh để xem gợi ý. Một hộp giới hạn hiển thị tên của chú chó cùng với mức độ tin cậy của mô hình.
- Nếu không có hộp giới hạn, hãy mở Công cụ của Chrome cho nhà phát triển, sau đó kiểm tra bảng điều khiển Bảng điều khiển để tìm lỗi hoặc xem lại các bước trước đó để đảm bảo rằng bạn không bỏ lỡ bất kỳ điều gì.
6. Chạy dự đoán trên video webcam trực tiếp
Phát hiện đối tượng
- Để phát hiện đối tượng trong một video webcam trực tiếp, hãy chuyển đến hàm
predictWebcam()
rồi thêm mã sau vào phần nội dung của hàm:
// 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);
Tính năng phát hiện đối tượng cho video sử dụng cùng một phương pháp bất kể bạn chạy suy luận dựa trên dữ liệu truyền trực tuyến hay video hoàn chỉnh. Phương thức detectForVideo()
tương tự như phương thức detect()
dùng cho ảnh, nhưng có thêm một tham số bổ sung cho dấu thời gian liên kết với khung hình hiện tại. Hàm này thực hiện việc phát hiện trực tiếp, vì vậy, bạn chuyển thời gian hiện tại làm dấu thời gian.
Quy trình và hiển thị nội dung gợi ý
- Để xử lý và hiển thị kết quả phát hiện, hãy chuyển đến hàm
displayVideoDetections()
rồi thêm mã sau vào phần nội dung của hàm:
// 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);
}
}
Mã này sẽ xoá mọi đối tượng được đánh dấu trước đó, sau đó tạo và hiển thị các thẻ <p>
để đánh dấu từng đối tượng được phát hiện.
Kiểm thử ứng dụng
Để kiểm tra tính năng phát hiện đối tượng trực tiếp, bạn nên có hình ảnh của một trong những chú chó mà mô hình được huấn luyện.
Để kiểm thử ứng dụng, hãy làm theo các bước sau:
- Tải một trong những bức ảnh về các chú chó xuống điện thoại của bạn.
- Trong ngăn xem trước, hãy nhấp vào Bật webcam.
- Nếu trình duyệt hiển thị một hộp thoại yêu cầu bạn cấp quyền truy cập vào webcam, hãy cấp quyền.
- Giữ ảnh chú chó trên điện thoại trước webcam. Một hộp giới hạn cho biết tên của chú chó và mức độ tin cậy của mô hình.
- Nếu không có hộp giới hạn, hãy mở Công cụ của Chrome cho nhà phát triển, sau đó kiểm tra bảng điều khiển Bảng điều khiển để tìm lỗi hoặc xem lại các bước trước đó để đảm bảo rằng bạn không bỏ lỡ bất kỳ điều gì.
7. Xin chúc mừng
Xin chúc mừng! Bạn đã xây dựng một ứng dụng web phát hiện các đối tượng trong hình ảnh. Để tìm hiểu thêm, hãy xem phiên bản hoàn chỉnh của ứng dụng trên CodePen.