---
# System prepended metadata

title: Hướng dẫn sử dụng Mô hình AI trên web

---

# Hướng dẫn sử dụng Mô hình AI trên web

## Yêu cầu:
- Cài đặt dependency: [@tensorflow/tfjs]('https://www.npmjs.com/package/@tensorflow/tfjs')
- Import method: `import * as tf from "@tensorflow/tfjs"`

## Cách sử dụng:
### Cách khởi động mô hình AI
- Folder gốc là public nên hãy đưa file mô hinh AI và folder public:
```jsx
const model = await tf.loadGraphModel('Đường dẫn đến mô hình ')
```
- Ví dụ:
```jsx=
const modelUrl = "/model.json";
const [model, setModel] = useState<tf.GraphModel<string | tf.io.IOHandler>>();
const loadModel = async (): Promise<void> => {
    try {
      const model = await tf.loadGraphModel(modelUrl);
      setModel(model);
      console.log("loaded Model");
    } catch (err) {
      console.log(err);
      console.log("failed load model");
    }
  };

```

### Cách đưa hình ảnh qua mô hình AI

- Tuỳ vào mỗi mô hình AI thì bên CoTAI sẽ cung cấp các function cụ thể để xử lý hình ảnh và trả về kết quả cụ thể.

Ví dụ:
```typescript=
let input : any
// predictModel chính là function CoTAI sẽ cung cấp
let output = await predictModel(input)
```

#### Mô hình nhận diện góc xe và tem
- Hình ảnh đưa vào mô hình cần phải là canvas: `HTMLCanvasElement`

```typescript=
type ModelOutput = Float32Array | Int32Array | Uint8Array;
const prediction = async (canv: HTMLCanvasElement) => {
    let boxesData: ModelOutput | undefined;
    let scoresData: ModelOutput | undefined;
    let classesData: ModelOutput | undefined;
    let validDetectionsData: number | undefined;
    if (model === undefined || model.inputs[0].shape === undefined) return;
    let [modelWidth, modelHeight] = model.inputs[0].shape.slice(1, 3);

    const input = tf.tidy(() => {
      return tf.image
        .resizeBilinear(tf.browser.fromPixels(canv), [modelWidth, modelHeight])
        .div(255.0)
        .expandDims(0);
    });

    if (input === undefined) {
      console.log("didnt have input");

      setTimeout(() => prediction(canv), 1);
      return;
    }

    await model.executeAsync(input).then((res) => {
      const [boxes, scores, classes, valid_detections] =
        res as tf.Tensor<tf.Rank>[];
      boxesData = boxes.dataSync();
      scoresData = scores.dataSync();
      classesData = classes.dataSync();
      validDetectionsData = valid_detections.dataSync()[0];

      // Set guide Text

      tf.disposeVariables();
      tf.dispose(res);
      tf.dispose(input);
    });

    return {
      boxesData,
      scoresData,
      classesData,
      validDetectionsData,
    };
  };
```

### Cách xử lí dữ liệu đầu ra của mô hình AI

- Tuỳ vào mỗi mô hình sẽ có các đầu ra khác nhau.

#### Mô hình nhận diện góc xe và tem

- `boundingBox` là dữ liệu của bounding box của chiếc xe, gồm 4 dữ liệu `[x1, y1, x2, y2]` tượng trưng cho `[xMin, yMin, xMax, yMax]` có kiểu dữ liệu là `number[]` và trong khoảng `0-1` của chiếc xe. Xử dụng dữ liệu này so sánh. Nếu `x1 >= 0.05 && x2 <= 0.95 && y1 >= 0.05 && y2 <= 0.95` (lưu ý: giá trị này chỉ là giá trị tham khảo, CoTAI sẽ cung cấp giá trị so sánh) có nghĩa là chiếc xe nằm trong khung hình và ngược lại.
- `validDetectionsData` là số lượng xe nhận diện được, có kiểu dữ liệu là `number`. Xử dụng hàm để xử lý trường hợp nhận diện được nhiều hơn 1 xe và không nhận diện được xe. Nếu nhận diện được 1 chiếc xe thì hiện bảng hướng dẫn.
- `classesData` là dữ liệu đại diện cho ID của Label có độ tự tin cao nhất, có kiểu dữ liệu là `number[]`. Vì điều kiện chỉ nhận một chiếc xe nên ta sẽ lấy giá trị đầu tiên trong danh sách `classesData[0]`
- `scoresData` là dữ liệu đại diện cho độ tự tin cao nhất, có kiểu dữ liệu là `number[]`. Vì điều kiện chỉ nhận một chiếc xe nên ta sẽ lấy giá trị đầu tiên trong danh sách `scoresData[0]`

```jsx=
let imageClass: string = "";
const boundingBox: number[] = Array.prototype.slice.call(boxesData?.slice(0, 4));
let [x1, y1, x2, y2] = boundingBox;
if (validDetectionsData === 0) {
    imageClass = "Không nhận diện được xe";
} else if (validDetectionsData === 0) {
    imageClass = "Có nhiều hơn một xe trong khung hình";
} else if (x1 >= 0.05 && x2 <= 0.95 && y1 >= 0.05 && y2 <= 0.95) {
    const klass = modelLabels[classesData[0]];
    const score = scoresData[0].toFixed(2);
    imageClass = `${klass}: ${score}`;
} else {
    imageClass = `Xe không nằm trong khung hình, ${x1} , ${x2}, ${x2}, ${y2}`;
}
```
***Label***
```jsx=
const modelLabels = [
  "back",
  "backLeft",
  "backRight",
  "front",
  "frontLeft",
  "frontRight",
  "left",
  "right",
  "stamp",
];
```
