Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 82 additions & 63 deletions docs/user-guide/inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,39 @@ This guide covers running inference with trained models.
Run inference on a single image:

```python
from mmdet.apis import init_detector, inference_detector
from visdet.apis import inference_detector, init_detector

config_file = 'configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py'
checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_coco.pth'
config_file = "configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py"
checkpoint_file = "checkpoints/faster_rcnn_r50_fpn_1x_coco.pth"

# Build the model from config and checkpoint
model = init_detector(config_file, checkpoint_file, device='cuda:0')
model = init_detector(config_file, checkpoint_file, device="cuda:0")

# Run inference on an image
result = inference_detector(model, 'demo/demo.jpg')
result = inference_detector(model, "demo/demo.jpg")
```

## Visualization

Display results:

```python
from mmdet.apis import show_result_pyplot

# Show the results
show_result_pyplot(model, 'demo/demo.jpg', result, score_thr=0.3)
```

Save results to file:

```python
from mmdet.apis import show_result_pyplot

model.show_result('demo/demo.jpg', result, out_file='result.jpg', score_thr=0.3)
from visdet.cv import imread
from visdet.visualization import DetLocalVisualizer

# DetLocalVisualizer expects RGB images
image = imread("demo/demo.jpg", channel_order="rgb")

visualizer = DetLocalVisualizer()
visualizer.dataset_meta = model.dataset_meta
visualizer.add_datasample(
"result",
image,
data_sample=result,
draw_gt=False,
out_file="result.jpg",
pred_score_thr=0.3,
)
```

## Batch Inference
Expand All @@ -44,16 +48,18 @@ Process multiple images:

```python
import glob
from mmdet.apis import inference_detector

from visdet.apis import inference_detector

# Get all images in a directory
image_files = glob.glob('path/to/images/*.jpg')
image_files = glob.glob("path/to/images/*.jpg")

for image_file in image_files:
result = inference_detector(model, image_file)
# Process result...
# Run as a batch for better performance
results = inference_detector(model, image_files)
```

`results` is a list of `DetDataSample` objects (one per input image).

### Multi-GPU Inference

To run inference on multiple GPUs in a single process, pass multiple CUDA devices to `init_detector` and then infer a batch (a list) of images:
Expand Down Expand Up @@ -92,40 +98,51 @@ dataset.compute_metadata() # populates sample.metadata.width/height
classes = model.dataset_meta.get("classes", [])
score_thr = 0.3

# 3) Run inference and attach detections
for sample in dataset.iter_samples(progress=True):
data_sample = inference_detector(model, sample.filepath)

pred = data_sample.pred_instances
pred = pred[pred.scores > score_thr]

width = sample.metadata.width
height = sample.metadata.height

dets = []
for bbox, label_id, score in zip(
pred.bboxes.cpu().numpy(),
pred.labels.cpu().numpy(),
pred.scores.cpu().numpy(),
strict=False,
):
x1, y1, x2, y2 = bbox.tolist()

dets.append(
{
"label": classes[int(label_id)] if classes else str(int(label_id)),
"bounding_box": [
x1 / width,
y1 / height,
(x2 - x1) / width,
(y2 - y1) / height,
],
"confidence": float(score),
}
)

sample["predictions"] = detections_to_fiftyone(dets)
sample.save()
# 3) Run streaming batched inference and attach detections
# (Batching is important for performance, and required for multi-GPU inference)
import itertools

batch_size = 8
sample_iter = dataset.iter_samples(progress=True)

while True:
sample_batch = list(itertools.islice(sample_iter, batch_size))
if not sample_batch:
break

data_samples = inference_detector(model, [s.filepath for s in sample_batch])

for sample, data_sample in zip(sample_batch, data_samples, strict=True):
pred = data_sample.pred_instances
pred = pred[pred.scores > score_thr]

width = sample.metadata.width
height = sample.metadata.height

dets = []
for bbox, label_id, score in zip(
pred.bboxes.cpu().numpy(),
pred.labels.cpu().numpy(),
pred.scores.cpu().numpy(),
strict=True,
):
x1, y1, x2, y2 = bbox.tolist()

dets.append(
{
"label": classes[int(label_id)] if classes else str(int(label_id)),
"bounding_box": [
x1 / width,
y1 / height,
(x2 - x1) / width,
(y2 - y1) / height,
],
"confidence": float(score),
}
)

sample["predictions"] = detections_to_fiftyone(dets)
sample.save()

# 4) Visualize in the FiftyOne App
session = fo.launch_app(dataset)
Expand Down Expand Up @@ -153,20 +170,20 @@ bash tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} --eval bbox
Create a custom inference pipeline:

```python
from mmdet.apis import init_detector
from mmcv import Config
from visdet.apis import inference_detector, init_detector
from visdet.engine.config import Config

# Load config
cfg = Config.fromfile('config.py')
cfg = Config.fromfile("config.py")

# Modify config if needed
cfg.model.test_cfg.score_thr = 0.5

# Initialize model
model = init_detector(cfg, 'checkpoint.pth', device='cuda:0')
model = init_detector(cfg, "checkpoint.pth", device="cuda:0")

# Run inference
result = inference_detector(model, 'image.jpg')
result = inference_detector(model, "image.jpg")
```

### Async Inference
Expand All @@ -175,10 +192,12 @@ For high-throughput scenarios:

```python
import asyncio
from mmdet.apis import init_detector, async_inference_detector

from visdet.apis import init_detector
from visdet.apis.inference import async_inference_detector

async def async_process():
model = init_detector(config_file, checkpoint_file, device='cuda:0')
model = init_detector(config_file, checkpoint_file, device="cuda:0")
tasks = [async_inference_detector(model, img) for img in images]
results = await asyncio.gather(*tasks)
return results
Expand Down
3 changes: 2 additions & 1 deletion visdet/apis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from visdet import models as _ # noqa: F401

from visdet.apis.det_inferencer import DetInferencer
from visdet.apis.inference import inference_detector, init_detector
from visdet.apis.inference import async_inference_detector, inference_detector, init_detector

__all__ = [
"DetInferencer",
"async_inference_detector",
"inference_detector",
"init_detector",
]
Loading