Image classification
Classification takes images as input and assigns a label to each image. In the core pipeline, classification selects the relevant images after extraction.
For example, label a flowchart 1 and any other figure 0. You can also define
several classes, such as CONSORT diagram, other flowchart, table and graph.
Classify images from a directory
classify_imgs()
takes a directory of images and saves their labels into one dedicated output
directory.
from pathlib import Path
from flowde.classify_fns.openai_classify_fn import make_openai_classify_fn
from flowde.classify_imgs import classify_imgs
img_dir = Path("results/extraction")
save_dir = Path("results/classification")
input_text = """
Classify whether this image is a flowchart.
Return 1 if it is a flowchart.
Return 0 if it is not a flowchart.
"""
classify_fn = make_openai_classify_fn(
input_text=input_text,
model="gpt-5.6-luna",
effort="medium",
)
labels = classify_imgs(
classify_fn=classify_fn,
img_dir=img_dir,
save_dir=save_dir,
positive_classes={1},
max_concurrent_jobs=1,
)
classify_imgs()
processes *.png files inside img_dir, in sorted path order.
Subdirectories are not searched. The returned labels list contains one label
per processed image: labels[0] corresponds to the first sorted image path,
labels[1] to the second sorted image path, and so on.
The example above uses OpenAI and requires the
OpenAI setup.
For classify_fn, you can use an OpenAI classifier created with
make_openai_classify_fn(),
a Gemini classifier created with
make_gemini_classify_fn(),
or your own classification function.
You can use positive_classes to save copies of images with selected labels.
For example, positive_classes={1} copies images labelled 1 into
save_dir / "positive_images" for use in the core pipeline's
image rotation or image parsing stage.
Without positive_classes, Flowde saves the labels without copying images.
make_openai_classify_fn()
creates a binary classification function by default, returning 0 or 1.
You can change the allowed labels through its result_structure parameter;
see multiclass classification.
Note: concurrency
max_concurrent_jobs controls how many calls to classify_fn can run
concurrently and defaults to 10. Parallel execution in
classify_imgs()
uses threads, allowing concurrency to greatly exceed the CPU core count
when waiting for API responses. Choose max_concurrent_jobs based on your
API limits.
See the
classify_imgs()
and
make_openai_classify_fn()
API references for full details of all parameters.
Classification results
In the example above, Flowde saves the labels and copies images labelled 1:
results/classification/
├── classifications.json
├── positive_images/
│ ├── paper-1_0.png
│ └── paper-2_0.png
└── .flowde/
classifications.json contains image paths and labels:
[
{ "img_path": "results/extraction/paper-1_0.png", "label": 1 },
{ "img_path": "results/extraction/paper-1_1.png", "label": 0 },
{ "img_path": "results/extraction/paper-2_0.png", "label": 1 }
]
.flowde records which images have been classified, their labels,
the classification settings and file fingerprints. Flowde uses this metadata
to resume the run and detect changes to the input images or saved results.
Resume classification
To continue an unfinished classification run whose results are saved in
save_dir, you can set on_existing="resume":
labels = classify_imgs(
classify_fn=classify_fn,
img_dir=img_dir,
save_dir=save_dir,
positive_classes={1},
max_concurrent_jobs=1,
on_existing="resume",
)
The .flowde directory inside save_dir stores the classification run's
state. Flowde uses these records to resume unfinished work and check the integrity
of the run.
Resume raises an error if the classifier's settings or positive_classes have
changed, or if previously classified input images or saved outputs have been
edited.
To use different settings, you can start a run in a new save_dir or replace
the previous run with on_existing="overwrite". See
managing runs for the full rules.
Multiclass classification
You can classify images into more than two categories. This example creates a classifier with five possible labels:
from typing import Literal
from flowde.classify_fns.classify_types import Classification
from flowde.classify_fns.openai_classify_fn import make_openai_classify_fn
class ImageTypeClassification(
Classification[Literal["consort", "other_flowchart", "table", "graph", "other"]]
):
pass
image_type_fn = make_openai_classify_fn(
input_text=(
"Classify this image as consort, other_flowchart, table, graph, or other. "
"Use consort for a CONSORT-style participant flow diagram."
),
model="gpt-5.6-luna",
effort="medium",
result_structure=ImageTypeClassification,
)
ImageTypeClassification defines the allowed labels using
Classification.
Passing this schema as result_structure to
make_openai_classify_fn()
creates a classifier that returns one of those five labels.
Bring your own classification function
You can write your own classifier and pass it to
classify_imgs()
as classify_fn. See the
custom classification tutorial
for the requirements your function must meet and a complete working example.
Next step
You can use save_dir / "positive_images" as the input directory for
image rotation or, if the copied images are already correctly
oriented, image parsing.