Metadata-Version: 2.5
Name: cardamage
Version: 0.1.1
Summary: Phát hiện tổn thất vật lý trên ô tô bằng Mask R-CNN R-101-DC5 (PyTorch thuần, không cần Detectron2)
Author: Naiscorp
License: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: car-damage,computer-vision,instance-segmentation,insurance,mask-rcnn
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: huggingface-hub>=0.24
Requires-Dist: numpy>=1.22
Requires-Dist: pillow>=9.0
Requires-Dist: safetensors>=0.4
Requires-Dist: torch>=2.0
Requires-Dist: torchvision>=0.15
Provides-Extra: demo
Requires-Dist: gradio>=4.0; extra == 'demo'
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Provides-Extra: onnx
Requires-Dist: onnxruntime>=1.16; extra == 'onnx'
Provides-Extra: serve
Requires-Dist: fastapi>=0.110; extra == 'serve'
Requires-Dist: python-multipart>=0.0.9; extra == 'serve'
Requires-Dist: uvicorn[standard]>=0.27; extra == 'serve'
Description-Content-Type: text/markdown

# cardamage

Phát hiện và phân vùng (instance segmentation) **7 loại tổn thất vật lý trên ô tô** từ ảnh.

Mask R-CNN R-101-DilatedC5 viết lại bằng **PyTorch thuần trong một file** — không cần cài
Detectron2, không cần biên dịch gì. Kết quả đã được đối chiếu với bản Detectron2 gốc đã
sinh ra trọng số; xem mục [Đối chiếu với Detectron2 gốc](#đối-chiếu-với-detectron2-gốc).

## Cài đặt

```bash
pip install cardamage
```

## Truy cập trọng số

Package này chỉ chứa **mã kiến trúc** (~40 KB), **không chứa trọng số**. Trọng số nằm ở
[`Naiscorp/car-damage-maskrcnn-r101-dc5`](https://huggingface.co/Naiscorp/car-damage-maskrcnn-r101-dc5)
trên Hugging Face, ở chế độ **gated**: trang model xem công khai được, nhưng tải file thì cần
tài khoản đã chấp nhận điều khoản.

Hai bước, làm một lần:

1. Mở trang model, bấm nút chấp nhận điều khoản.
2. Đăng nhập bằng token có quyền đọc: `hf auth login`.

Chưa làm thì `from_pretrained(...)` báo:

```
RepositoryNotFoundError: 401 Client Error.
Repository Not Found for url: https://huggingface.co/Naiscorp/car-damage-maskrcnn-r101-dc5/...
```

Thông báo ghi "Not Found" nhưng nguyên nhân thật là **thiếu quyền đọc** — không phải lỗi cài đặt.

### Trên Kaggle / Colab

Notebook không có sẵn token nên luôn bị 401. Lưu token vào secret rồi đăng nhập trước khi gọi
`from_pretrained`:

```python
from huggingface_hub import login

# Kaggle: Add-ons -> Secrets -> them secret ten HF_TOKEN
from kaggle_secrets import UserSecretsClient
login(UserSecretsClient().get_secret("HF_TOKEN"))

# Colab: bieu tuong chia khoa ben trai -> them secret ten HF_TOKEN
# from google.colab import userdata
# login(userdata.get("HF_TOKEN"))
```

## Dùng thử

```python
import torch
from PIL import Image
from cardamage import AutoModel

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = AutoModel.from_pretrained("Naiscorp/car-damage-maskrcnn-r101-dc5").to(device).eval()

overlay = model.inference(Image.open("xe.jpg"))   # PIL.Image đã vẽ mask
overlay.save("ket_qua.png")
```

Cần kết quả có cấu trúc thay vì ảnh:

```python
r = model.predict(Image.open("xe.jpg"))
r["boxes"]      # (N, 4) float32, xyxy trên toạ độ ảnh gốc
r["scores"]     # (N,)   float32
r["classes"]    # (N,)   int64, 0..6
r["labels"]     # list[str] tiếng Việt
r["labels_en"]  # list[str] tiếng Anh
r["masks"]      # (N, H, W) bool, đã dán về kích thước ảnh gốc
```

## 7 lớp tổn thất

| id | Tiếng Việt | English |
|---:|---|---|
| 0 | Móp lõm | Dent |
| 1 | Trầy sơn | Paint scratch |
| 2 | Rách | Tear |
| 3 | Mất bộ phận | Missing part |
| 4 | Thủng | Puncture |
| 5 | Bể đèn | Broken lamp |
| 6 | Vỡ kính | Broken glass |

## Tuỳ chỉnh

```python
model.score_thresh = 0.5          # mặc định 0.7
model.inference(img, language="en", alpha=0.6, draw_boxes=False)
```

### Nhãn tiếng Việt bị vẽ thành ô vuông?

Máy không có font Unicode nào (hay gặp trên container tối giản). Package tự dò font hệ thống
và font đi kèm `matplotlib`; không tìm được font phủ đủ dấu thì nó **tự chuyển sang nhãn tiếng
Anh** kèm cảnh báo, thay vì vẽ ô vuông. Muốn có nhãn tiếng Việt:

```bash
apt-get install -y fonts-dejavu-core     # hoac: pip install matplotlib
```

## Chạy bằng ONNX (không cần PyTorch)

```bash
pip install onnxruntime pillow numpy huggingface_hub
python onnx_run.py xe.jpg ket_qua.png
```

## Đối chiếu với Detectron2 gốc

Bộ kiểm chứng `check_parity.py` chạy 14 ảnh test và so từng box, từng score, từng pixel mask
với kết quả của bản Detectron2 0.6 đã sinh ra trọng số:

| Môi trường | Kết quả |
|---|---|
| torch 2.5.1 + CUDA (môi trường sinh ra bản đối chiếu) | **14/14 ảnh trùng từng bit**, mask khớp từng pixel |
| torch 2.13 + CUDA | Cùng số detection, sai lệch ≤ 2.1e-1 px trên box và ≤ 2.0e-3 trên score |
| torch 2.5.1 + CPU | Cùng số detection, sai lệch ≤ 3.0e+0 px trên box và ≤ 7.6e-4 trên score |

**Số detection không đổi trong mọi tổ hợp** — không có tổn thất nào xuất hiện thêm hay biến mất.
Sai lệch là nhiễu dấu phẩy động do khác kernel/phiên bản, không phải khác mô hình.

Một hệ quả cần biết: khi hai detection có score gần bằng nhau, nhiễu này có thể **đảo thứ tự**
của chúng trong danh sách trả về. Đã quan sát được một ca: hai detection cách nhau `1.67e-4`
điểm đổi chỗ cho nhau (vẫn đúng class, đúng box). **Đừng dựa vào thứ tự phần tử** — hãy lọc
theo `scores` và `classes`.

## Giấy phép

Mã nguồn: **Apache-2.0** (xem `LICENSE` và `NOTICE` — package tái hiện thuật toán suy luận
của Detectron2, cũng Apache-2.0).

**Trọng số model theo giấy phép riêng, không nằm trong Apache-2.0.** Xem model card trên
Hugging Face trước khi dùng cho mục đích thương mại.
