Rotation benchmarking
Rotation benchmarking evaluates how well a rotation classification function has performed against a set of ground-truth rotation labels.
In a typical workflow, you will first run image rotation and save the predicted rotations to JSON. You can then compare those predictions against a separate JSON file containing the true rotations.
Input format
Rotation benchmarks compare two JSON files:
- a ground-truth file containing the true rotation labels;
- a prediction file containing the predicted rotation labels.
Rotation saves predictions automatically to save_dir / "rotations.json".
Pass that file to the benchmark as pred_path. The benchmark reads saved JSON
and makes no model requests.
Both files should contain a list of objects with the following keys:
[
{
"img_path": "data/flowchart-images/paper-1_0.png",
"label": 0
},
{
"img_path": "data/flowchart-images/paper-1_1.png",
"label": 90
}
]
The label is the clockwise rotation, in degrees, needed to correct the image
orientation: 0, 90, 180 or 270. Ground-truth labels describe the
corrections needed by the original input images.
The benchmark expects the true and predicted files to contain the same images in the same order. The parent directories do not have to match, but the image filenames must match.
For example, this is valid:
true: data/ground-truth-rotations/paper-1_0.png
pred: data/predicted-rotations/paper-1_0.png
This is not valid:
true: data/ground-truth-rotations/paper-1_0.png
pred: data/predicted-rotations/paper-2_0.png
Rotation benchmark
You can use
RotationBenchmark
to evaluate predicted rotation labels:
from pathlib import Path
from flowde.benchmarks.rotation.rotation_benchmark import RotationBenchmark
benchmark = RotationBenchmark(
true_path=Path("data/true-rotations.json"),
pred_path=Path("data/pred-rotations.json"),
)
The benchmark loads both JSON files, checks that they are valid, and compares the predicted rotation labels with the true rotation labels.
The benchmark uses the labels (0, 90, 180, 270) automatically and includes
every angle in its counts and confusion matrix, even when no image has that
label. A prediction counts as correct only when the predicted angle exactly
matches the ground-truth angle.
See the
RotationBenchmark
API reference for full details of the parameters and results.
Rotation benchmark results
After creating the benchmark object, you can inspect the results through its properties.
| Property | Description |
|---|---|
len(benchmark) |
Number of images in the benchmark. |
benchmark.result_list |
All rotation results, one per image. |
benchmark.correct_predictions |
Results where pred matches true. |
benchmark.incorrect_predictions |
Results where pred does not match true. |
benchmark.accuracy |
Proportion of images where the predicted angle matches the ground-truth angle. |
benchmark.img_paths |
Image paths used in the benchmark. |
benchmark.trues |
Ground-truth angles, in benchmark order. |
benchmark.preds |
Predicted angles, in benchmark order. |
benchmark.labels |
The supported rotation labels: (0, 90, 180, 270). |
benchmark.confusion_matrix |
Number of images for each ground-truth angle and predicted angle pair. |
benchmark.num_per_true_class |
Number of images requiring each ground-truth angle. |
benchmark.num_per_pred_class |
Number of images assigned each predicted angle. |
benchmark.per_class_accuracy |
For each ground-truth angle, the proportion of images with a correct prediction; 0.0 when no image requires that angle. |
For example, you can print the overall accuracy and class-level summaries:
print(f"Accuracy: {benchmark.accuracy:.3f}")
print(benchmark.confusion_matrix)
print(benchmark.num_per_true_class)
print(benchmark.num_per_pred_class)
print(benchmark.per_class_accuracy)
The confusion matrix is a nested dictionary indexed by ground-truth angle,
then predicted angle. For example, benchmark.confusion_matrix[90][0] counts
images that needed a 90-degree clockwise correction but received a prediction
of 0.
You can also inspect the individual incorrect predictions:
for result in benchmark.incorrect_predictions:
print(result.img_path)
print(f"true: {result.true}")
print(f"pred: {result.pred}")
Each item in result_list, correct_predictions, and incorrect_predictions
is a
SingleClassificationResult
with:
| Attribute | Description |
|---|---|
img_path |
Image path from the ground-truth file. |
true |
Ground-truth clockwise correction, in degrees. |
pred |
Predicted clockwise correction, in degrees. |
See the
RotationBenchmark
API reference for full details of the parameters and results.