Bộ lọc chuyển động cho Vertex AI Vision

1. Mục tiêu

Tổng quan

Lớp học lập trình này tập trung vào việc tạo một ứng dụng Vertex AI Vision toàn diện để minh hoạ việc gửi video bằng tính năng lọc chuyển động. Trong hướng dẫn này, chúng ta sẽ tìm hiểu về các tham số khác nhau trong cấu hình bộ lọc chuyển động:

  • Độ nhạy phát hiện chuyển động
  • Thời lượng sự kiện tối thiểu
  • Giai đoạn xem lại
  • Thời gian hạ nhiệt
  • Vùng phát hiện chuyển động

Kiến thức bạn sẽ học được

  • Cách nhập video để phát trực tiếp
  • Các tính năng có trong Bộ lọc chuyển động và cách sử dụng chúng
  • Nơi kiểm tra số liệu thống kê của Bộ lọc chuyển động
  • Cách điều chỉnh chế độ cài đặt dựa trên video

2. Trước khi bắt đầu

  1. Trong bảng điều khiển Google Cloud, trên trang bộ chọn dự án, hãy chọn hoặc tạo một dự án Google Cloud. Lưu ý: Nếu bạn không định giữ lại tài nguyên mà bạn tạo trong quy trình này, hãy tạo một dự án thay vì chọn một dự án hiện có. Sau khi hoàn tất những bước này, bạn có thể xoá dự án, đồng thời xoá tất cả tài nguyên được liên kết với dự án. Chuyển đến bộ chọn dự án
  2. Đảm bảo rằng bạn đã bật tính năng thanh toán cho dự án trên Google Cloud. Tìm hiểu cách kiểm tra xem tính năng thanh toán có được bật trên một dự án hay không.
  3. Bật Compute Engine và Vision AI API. Bật API

Tạo tài khoản dịch vụ:

  1. Trong bảng điều khiển Google Cloud, hãy chuyển đến trang Tạo tài khoản dịch vụ. Chuyển đến trang Tạo tài khoản dịch vụ
  2. Chọn dự án của bạn.
  3. Trong trường Tên tài khoản dịch vụ, hãy nhập tên. Bảng điều khiển Google Cloud sẽ điền vào trường Mã tài khoản dịch vụ theo tên này. Trong trường Mô tả tài khoản dịch vụ, hãy nhập nội dung mô tả. Ví dụ: Tài khoản dịch vụ để bắt đầu nhanh.
  4. Nhấp vào Tạo và tiếp tục.
  5. Để cấp quyền truy cập vào dự án của bạn, hãy cấp(các) vai trò sau cho tài khoản dịch vụ của bạn: Vision AI > Người chỉnh sửa Vision AI, Compute Engine > Quản trị viên của phiên bản điện toán (thử nghiệm), Bộ nhớ > Trình xem đối tượng lưu trữ † . Trong danh sách Chọn vai trò, hãy chọn một vai trò. Để có các vai trò khác, hãy nhấp vào Thêm vai trò khác rồi thêm từng vai trò. Lưu ý: Trường Vai trò ảnh hưởng đến những tài nguyên mà tài khoản dịch vụ của bạn có thể truy cập trong dự án. Bạn có thể thu hồi các vai trò này hoặc cấp thêm vai trò sau này. Trong môi trường phát hành công khai, không được cấp vai trò Chủ sở hữu, Người chỉnh sửa hoặc Người xem. Thay vào đó, hãy cấp một vai trò được xác định trước hoặc vai trò tuỳ chỉnh đáp ứng nhu cầu của bạn.
  6. Nhấp vào Tiếp tục.
  7. Nhấp vào Xong để hoàn tất việc tạo tài khoản dịch vụ. Đừng đóng cửa sổ trình duyệt. Bạn sẽ dùng chỉ mục này trong bước tiếp theo.

Tạo khoá tài khoản dịch vụ:

  1. Trong bảng điều khiển Google Cloud, hãy nhấp vào địa chỉ email của tài khoản dịch vụ mà bạn đã tạo.
  2. Nhấp vào Khoá.
  3. Nhấp vào Thêm khoá, rồi nhấp vào Tạo khoá mới.
  4. Nhấp vào Tạo. Một tệp khoá JSON được tải xuống máy tính của bạn.
  5. Nhấp vào Đóng.
  6. Cài đặtkhởi động Google Cloud CLI.

† Chỉ cần có vai trò nếu bạn sao chép tệp video mẫu từ một bộ chứa Cloud Storage.

3. Bộ lọc chuyển động

Bộ lọc chuyển động ghi lại các đoạn video sản phẩm và chuyển động có chứa sự kiện chuyển động. Khi điều chỉnh độ nhạy của chuyển động, thời lượng tối thiểu của sự kiện, giai đoạn xem lại, thời gian chờ và vùng phát hiện chuyển động, người dùng có thể thiết lập bộ lọc dựa trên nhu cầu của mình.

Cấu hình bộ lọc chuyển động

Có 5 cấu hình có sẵn trong bộ lọc chuyển động để tuỳ chỉnh.

  1. Độ nhạy chuyển động: mức độ nhạy cảm khi chuyển động được kích hoạt.
  2. Thời lượng sự kiện tối thiểu: độ dài tối thiểu mà một sự kiện chuyển động sẽ được ghi lại.
  3. Giai đoạn xem lại: thời lượng video bắt đầu quay trước khi phát hiện sự kiện chuyển động.
  4. Thời gian chờ: sau khi một sự kiện chuyển động kết thúc, thời gian chờ trong khoảng thời gian đã chỉ định sẽ diễn ra. Trong thời gian chờ, các sự kiện chuyển động sẽ không được kích hoạt.
  5. Vùng phát hiện chuyển động: vùng do người dùng định cấu hình để chỉ định vị trí sẽ chạy tính năng phát hiện chuyển động. (Sẽ được giải thích chi tiết ở phần sau)

Độ nhạy chuyển động

Sử dụng cờ motion_detection_sensitivity trong lệnh vaictl.Chuỗi
. Phương tiện mặc định. Có thể chọn thấp, trung bình hoặc cao.

Độ nhạy phát hiện chuyển động càng cao thì càng nhạy cảm với tiếng ồn và chuyển động nhỏ hơn. Bạn nên sử dụng chế độ cài đặt này cho các chế độ cài đặt có các vật thể đang chuyển động nhỏ hơn (chẳng hạn như những người ở xa) và có ánh sáng ổn định.

Mặt khác, độ nhạy thấp ít nhạy cảm hơn với hiện tượng nhiễu ánh sáng. Chế độ cài đặt này phù hợp khi có nhiều nhiễu ánh sáng hơn, chẳng hạn như môi trường ngoài trời, và khi video có chất lượng thấp, nơi có thể có nhiều tiếng ồn hơn. Vì chế độ cài đặt này là chế độ lọc linh hoạt nhất trong tất cả các chế độ cài đặt, nên chế độ này có thể bỏ qua chuyển động từ các đối tượng nhỏ.

Thời lượng sự kiện tối thiểu

Sử dụng cờ min_event_length_in_seconds trong lệnh vaictl.
Số nguyên. Mặc định là 10 giây. Phạm vi từ 0 giây đến 3600 giây.

Thời lượng tối thiểu của video sự kiện chuyển động sẽ được phân tích cú pháp sau khi phát hiện thấy một đoạn sự kiện chuyển động trong khung hình.

Giai đoạn xem lại

Sử dụng cờ look_back_window_in_seconds trong lệnh vaictl.
Số nguyên. Mặc định là 3 giây. Phạm vi từ 0 giây đến 3600 giây.

Giai đoạn xem lại là thời lượng được lưu vào bộ nhớ đệm trước khi phát hiện một sự kiện chuyển động. Tính năng này rất hữu ích khi chúng ta muốn xem những gì xảy ra trong khung hình một vài giây trước khi phát hiện sự kiện chuyển động.

Thời gian chờ

Sử dụng cờ cool_down_period_in_seconds trong lệnh vaictl.
Số nguyên. Mặc định 300 giây. Phạm vi từ 0 giây đến 3600 giây.

Thời gian chờ là khoảng thời gian tạm dừng tính năng phát hiện chuyển động sau khi ghi lại một sự kiện chuyển động. Trong thời gian chờ, hệ thống sẽ không chạy phép tính nào để phát hiện chuyển động.

4. Ví dụ về bộ lọc chuyển động cơ bản

Hướng dẫn sử dụng SDK Vaictl

Để xem hướng dẫn sử dụng của vaictl về luồng đầu vào có bộ lọc chuyển động, hãy dùng lệnh bên dưới.

vaictl send video-file applying motion-filter -h

Chuẩn bị một video mẫu

  1. Bạn có thể sao chép video mẫu bằng lệnh GCR cp sau. Thay thế biến sau:
  • NGUỒN: Vị trí của tệp video sẽ sử dụng. Bạn có thể sử dụng nguồn tệp video của riêng mình (ví dụ: gs://BUCKET_NAME/FILENAME.mp4) hoặc sử dụng video mẫu (gs://cloud-samples-data/vertex-ai-vision/street_vehicles_people.mp4 )(video có người và xe cộ, nguồn)
export SOURCE=gs://cloud-samples-data/vertex-ai-vision/street_vehicles_people.mp4
gsutil cp $SOURCE .

Chuẩn bị các biến môi trường

Đặt các biến môi trường bên dưới để sử dụng mẫu lệnh được cung cấp.

biến vaictl

  • PROJECT_ID: Mã dự án trên Google Cloud của bạn.
  • LOCATION_ID: ID vị trí của bạn. Ví dụ: us-central1. Để biết thêm thông tin, hãy xem bài viết Vị trí đám mây.
  • LOCAL_FILE: Tên tệp của tệp video cục bộ. Ví dụ: Street_vehicles_people.mp4.
  • – cờ lặp: Không bắt buộc. Lặp lại dữ liệu tệp để mô phỏng hoạt động truyền trực tuyến.
export PROJECT_ID=<Your Google Cloud project ID>
export LOCATION_ID=us-central1

Biến bộ lọc chuyển động

  • MOTION_SENSITIVITY: Độ nhạy của tính năng phát hiện chuyển động.
  • MIN_EVENT_LENGTH: Thời lượng tối thiểu của sự kiện chuyển động.
  • Look_BACK_WINDOW: Thời gian để chụp trước chuyển động đầu tiên trong một sự kiện chuyển động.
  • COOL_DOWN_PERIOD: Khoảng thời gian mà tính năng phát hiện chuyển động sẽ tạm dừng sau khi ghi lại một sự kiện chuyển động.
export MOTION_SENSITIVITY=<low or medium or high>
export MIN_EVENT_LENGTH=<0-3600>
export LOOK_BACK_WINDOW=<0-3600>
export COOL_DOWN_PERIOD=<0-3600>

Chuẩn bị lệnh lọc chuyển động

Có hai cách để dùng bộ lọc chuyển động với luồng dữ liệu đầu vào. Lựa chọn đầu tiên là gửi sự kiện chuyển động đến một luồng trong bảng điều khiển Cloud. Lựa chọn thứ hai là gửi sự kiện chuyển động đến bộ nhớ cục bộ.

Gửi kết quả đến Cloud Console

Bạn có thể sử dụng vaictl để truyền dữ liệu video đầu ra lên Cloud Console. Bắt đầu bằng cách kích hoạt Vision AI API trong Cloud Console.

Đăng ký sự kiện phát trực tiếp mới

  1. Thẻ Lượt nhấp vào luồng trên bảng điều khiển bên trái của Vertex AI Vision.
  2. Nhấp vào Đăng ký
  3. Trong tên Luồng, hãy nhập motion-detection-stream
  4. Trong khu vực, hãy nhập us-central1
  5. Đăng ký lượt nhấp

Đang gửi kết quả để truyền trực tuyến

Lệnh này truyền trực tuyến tệp video đến một luồng. Nếu bạn sử dụng cờ –loop, video sẽ được lặp lại trong luồng cho đến khi bạn dừng lệnh. Chúng ta sẽ chạy lệnh này dưới dạng một công việc trong nền để nó tiếp tục truyền trực tuyến.

Thêm nohup ở đầu và & ở cuối để thiết lập lệnh ở chế độ nền.

INPUT_VIDEO=street_vehicles_people.mp4

vaictl -p $PROJECT \
       -l $LOCATION_ID \
       -c application-cluster-0 \
       --service-endpoint visionai.googleapis.com \
  send video-file  --file-path $INPUT_VIDEO \
  applying motion-filter
         --motion-sensitivity=$MOTION_SENSITIVITY \
         --min-event-length=$MIN_EVENT_LENGTH \
         --lookback-length=$LOOK_BACK_WINDOW \
         --cooldown-length=$COOL_DOWN_PERIOD \
  to streams motion-detection-stream --loop

Có thể mất khoảng 100 giây từ khi bắt đầu thao tác nhập vaictl đến khi video xuất hiện trong trang tổng quan.

Sau khi có quy trình truyền dẫn sự kiện phát trực tiếp, bạn có thể xem nguồn cấp dữ liệu video trong thẻ Luồng của trang tổng quan Vertex AI Vision bằng cách chọn luồng lưu lượng truy cập.

Chuyển đến thẻ Bảng tin

Gửi kết quả đến bộ nhớ cục bộ

Lệnh này truyền trực tuyến tệp video đến một luồng.

Thêm nohup ở đầu và & ở cuối để thiết lập lệnh ở chế độ nền.

INPUT_VIDEO=street_vehicles_people.mp4
OUTPUT_PATH=<path_to_store_motion_events_on_local_disk>

nohup vaictl -p $PROJECT \
             -l $LOCATION_ID \
             -c application-cluster-0 \
             --service-endpoint visionai.googleapis.com \
  send video-file  --file-path $INPUT_VIDEO \
  applying motion-filter
         --motion-sensitivity=$MOTION_SENSITIVITY \
         --min-event-length=$MIN_EVENT_LENGTH \
         --lookback-length=$LOOK_BACK_WINDOW \
         --cooldown-length=$COOL_DOWN_PERIOD \
  to mp4file --mp4-file-path=$OUTPUT_PATH --loop

5. Vùng phát hiện chuyển động

Trong phần này, chúng ta sẽ đi sâu vào cách sử dụng vùng phát hiện chuyển động và cách định cấu hình vùng đó. Mục đích của vùng này là để cải thiện khả năng phát hiện chuyển động bằng cách che đi chuyển động đến từ các khu vực mà bạn không quan tâm.

Vùng phát hiện chuyển động có hai loại, (1) vùng tích cực trong đó tính năng phát hiện chuyển động chỉ chạy trong vùng được chú thích; (2) vùng âm, nơi tính năng phát hiện chuyển động bỏ qua mọi chuyển động trong vùng được chú thích.

Chú thích vùng

Sử dụng cờ zone_annotation trong lệnh vaictl để nhập toạ độ cho đa giác vùng.Chuỗi
. Giá trị mặc định trống cho chú thích vùng.

Chú thích vùng sẽ là một chuỗi dữ liệu do người dùng nhập vào, cho biết các vùng trong khung mà người dùng muốn ẩn hoặc lấy tiêu điểm. Để chú thích vùng, người dùng sẽ cần chỉ định toạ độ hình ảnh của trục x và y cho mỗi nút trong vùng đó. Một vùng cần có từ 3 nút trở lên để tạo thành một đa giác. Có thể có nhiều vùng trong một khung hình. Nếu các khu vực chồng lên nhau, thì khu vực bị che phủ bởi cả hai khu vực vẫn sẽ bị che phủ.

Chú giải vùng có một cú pháp nhập cụ thể theo sau.

  • Để biểu thị một nút, hãy sử dụng : để kết nối trục x và y của toạ độ hình ảnh. Ví dụ: một nút của (0,0) ở góc trên bên trái sẽ được biểu thị là 0:0.
  • Để biểu thị tất cả các nút trong một vùng, hãy sử dụng ; để kết nối các nút. Ví dụ: đối với một vùng có các nút (0,0), (100,0), (100,100)(0, 100), vùng này sẽ được biểu thị là 0:0;100:0;100:100;0:100. Luôn nhập các nút dưới dạng các nút kết nối cạnh nhau, thứ tự có thể là cả chiều kim đồng hồ hoặc ngược chiều kim đồng hồ.

Vùng phát hiện chuyển động – hình vuông*Một vùng hình vuông có 4 nút.

Vùng phát hiện chuyển động – hình tam giác*Một vùng tam giác có 3 nút.

  • Để biểu thị nhiều vùng trong một khung, hãy sử dụng - để kết nối các vùng khác nhau. Ví dụ: nếu chúng ta muốn nhập cả (0,0), (100,0), (100,100), (0,100)(120,120), (110,150), (200,160), chú thích vùng nhập sẽ là 0:0;100:0;100:100;0:100-120:120;110:150;200:160.

Vùng phát hiện chuyển động – một khung hình có hai vùng*Hai vùng trong một khung hình.

Để lấy toạ độ từ hình ảnh, bạn có thể dùng một số công cụ trực tuyến để lấy toạ độ. Ví dụ: xem Wolfram – Lấy toạ độ từ hình ảnh

Loại trừ vùng được chú thích

Sử dụng cờ exclude_annotated_zone trong lệnh vaictl để định cấu hình phát hiện chuyển động trong vùng hoặc bên ngoài vùng.
Boolean. Mặc định là sai.

Loại trừ vùng được chú thích là giá trị nhập vào boolean từ người dùng, cho biết liệu người dùng có muốn loại trừ vùng được chú thích trong tính năng phát hiện chuyển động hay không.

  • Nếu bạn đặt thành true, vùng được chú thích sẽ đóng vai trò là vùng âm. Sẽ không phát hiện được chuyển động trong các vùng được chú thích.

Vùng phát hiện chuyển động – lựa chọn loại trừ *Chỉ chạy tính năng phát hiện chuyển động bên ngoài vùng đầu vào.

  • Nếu bạn đặt chính sách này thành false, thì vùng này sẽ đóng vai trò là vùng dương tính, nơi tập trung vào việc phát hiện chuyển động.

Vùng phát hiện chuyển động – có cả lựa chọn *Chỉ chạy tính năng phát hiện chuyển động trong vùng đầu vào.

6. Ví dụ về bộ lọc chuyển động cho vùng phát hiện chuyển động

Trong ví dụ này, chúng ta sẽ sử dụng video có một cái cây liên tục di chuyển ở tiền cảnh. Ở chế độ cài đặt bộ lọc chuyển động thông thường, video sẽ chỉ tạo ra một sự kiện chuyển động có thời lượng của video gốc vì bộ lọc chuyển động ghi nhận cây chuyển động là "di chuyển liên tục trong toàn bộ video". Tuy nhiên, với sự trợ giúp của vùng phát hiện chuyển động, chúng ta có thể che chuyển động từ cây một cách thích hợp và tập trung vào chuyển động của ô tô và người đi bộ.

Chuẩn bị video

Video mẫu (gs://cloud-samples-data/vertex-ai-vision/dynamic-background-fall.mp4) chứa nội dung về cây cối, ô tô và người đi bộ trên trang www.changedetection.net.

Ghi nhận quyền tác giả của video: N. Goyette, P.-M. Jodoin, F. Porikli, J. Konrad và P. Ishwar, changedetection.net: Tập dữ liệu điểm chuẩn phát hiện thay đổi mới trong Proc. Hội thảo của IEEE về phát hiện thay đổi (CDW-2012) tại CVPR-2012, Offernce, RI, 16-21 tháng 6, 2012

Chuẩn bị biến môi trường

Biến dự án trên đám mây của Google.

export PROJECT_ID=<Your Google Cloud project ID>
export LOCATION_ID=us-central1
export LOCAL_FILE=street_vehicles_people.mp4

Cấu hình bộ lọc chuyển động cơ bản.

export MOTION_SENSITIVITY=<low or medium or high>
export MIN_EVENT_LENGTH=<0-3600>
export LOOK_BACK_WINDOW=<0-3600>
export COOL_DOWN_PERIOD=<0-3600>

Cấu hình vùng phát hiện chuyển động.

Chọn từ bên dưới để xem cách sử dụng khác cho vùng phát hiện chuyển động.

Loại trừ cây cho phát hiện chuyển động.

export ZONE_ANNOTATION="0:0;680:0;660:70;380:320;100:150"
export EXCLUDE_ANNOTATED_ZONE=true

Vùng phát hiện chuyển động – loại trừ tính năng phát hiện chuyển động khỏi vùng được chú thích trong video ví dụ *Chỉ chạy tính năng phát hiện chuyển động bên ngoài vùng đầu vào.

Lấy tiêu điểm tính năng phát hiện chuyển động trên đường.

export ZONE_ANNOTATION="0:300;780:300;780:480;0:480"
export EXCLUDE_ANNOTATED_ZONE=false

Vùng phát hiện chuyển động – chạy tính năng phát hiện chuyển động từ vùng được chú thích trong video ví dụ *Chỉ chạy tính năng phát hiện chuyển động bên ngoài vùng đầu vào.

Gửi luồng video bằng bộ lọc chuyển động

Gửi sự kiện chuyển động đến Cloud Console

Bạn có thể sử dụng vaictl để truyền dữ liệu video đầu ra lên Cloud Console. Bắt đầu bằng cách kích hoạt Vision AI API trong Cloud Console.

Đăng ký sự kiện phát trực tiếp mới

  1. Thẻ Lượt nhấp vào luồng trên bảng điều khiển bên trái của Vertex AI Vision.
  2. Nhấp vào Đăng ký
  3. Trong tên Luồng, hãy nhập motion-detection-stream
  4. Trong khu vực, hãy nhập us-central1
  5. Đăng ký lượt nhấp

Đang gửi kết quả để truyền trực tuyến

Lệnh này truyền trực tuyến tệp video đến một luồng. Nếu bạn sử dụng cờ –loop, video sẽ được lặp lại trong luồng cho đến khi bạn dừng lệnh. Chúng ta sẽ chạy lệnh này dưới dạng một công việc trong nền để nó tiếp tục truyền trực tuyến.

Thêm nohup ở đầu và & ở cuối để thiết lập lệnh ở chế độ nền.

vaictl -p $PROJECT \
       -l $LOCATION_ID \
       -c application-cluster-0 \
       --service-endpoint visionai.googleapis.com \
  send video-file  --file-path $INPUT_VIDEO \
  applying motion-filter
         --motion-sensitivity=$MOTION_SENSITIVITY \
         --min-event-length=$MIN_EVENT_LENGTH \
         --lookback-length=$LOOK_BACK_WINDOW \
         --cooldown-length=$COOL_DOWN_PERIOD \
         --zone_annotation=ZONE_ANNOTATION \
         --exclude_annotated_zone=$EXCLUDE_ANNOTATED_ZONE \
  to streams motion-detection-stream --loop

Có thể mất khoảng 100 giây từ khi bắt đầu thao tác nhập vaictl đến khi video xuất hiện trong trang tổng quan.

Sau khi có quy trình truyền dẫn sự kiện phát trực tiếp, bạn có thể xem nguồn cấp dữ liệu video trong thẻ Luồng của trang tổng quan Vertex AI Vision bằng cách chọn luồng lưu lượng truy cập.

Chuyển đến thẻ Bảng tin

Gửi kết quả đến bộ nhớ cục bộ

Lệnh này truyền trực tuyến tệp video đến một luồng. Nếu bạn sử dụng cờ –loop, video sẽ được lặp lại trong luồng cho đến khi bạn dừng lệnh. Chúng ta sẽ chạy lệnh này dưới dạng một công việc trong nền để nó tiếp tục truyền trực tuyến.

Thêm nohup ở đầu và & ở cuối để thiết lập lệnh ở chế độ nền.

OUTPUT_PATH=<path_to_store_motion_events>

vaictl -p $PROJECT \
       -l $LOCATION_ID \
       -c application-cluster-0 \
       --service-endpoint visionai.googleapis.com \
  send video-file  --file-path $INPUT_VIDEO \
  applying motion-filter
         --motion-sensitivity=$MOTION_SENSITIVITY \
         --min-event-length=$MIN_EVENT_LENGTH \
         --lookback-length=$LOOK_BACK_WINDOW \
         --cooldown-length=$COOL_DOWN_PERIOD \
         --zone_annotation=$ZONE_ANNOTATION \
         --exclude_annotated_zone=$EXCLUDE_ANNOTATED_ZONE \
  to mp4file --mp4-file-path=$OUTPUT_PATH --loop

7. Xin chúc mừng

Xin chúc mừng, bạn đã hoàn thành phòng thí nghiệm!

Dọn dẹp

Để tránh bị tính phí vào tài khoản Google Cloud của bạn cho các tài nguyên được sử dụng trong hướng dẫn này, hãy kết thúc hoạt động vaictl SDK thông qua dòng lệnh bằng ctrl + z.

Tài nguyên

https://cloud.google.com/vision-ai/docs/overview

https://cloud.google.com/vision-ai/docs/motion-filtering-model

https://cloud.google.com/vision-ai/docs/create-manage-streams

Phản hồi

Nhấp vào đây để cung cấp ý kiến phản hồi

Khảo sát

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ có thể đọc Đọc và hoàn thành bài tập

Lớp học lập trình này có hữu ích không?

Rất hữu ích hữu ích vừa phải