Automated Macroscopic Fabric and Orientation Analysis for ceramic sherds
Project description
AMFOrA (Automated Macroscopic Fabric and Orientation Analysis)
A Python package for automated quantitative analysis of ceramic sherd fabric from flatbed-scanner images — inclusion detection, void analysis, size and orientation measurements, and color characterization.
Built for archaeological and materials-science workflows that need reproducible, DPI-aware measurements across many sherds.
Features
- Inclusion detection — Blob and contour-based detectors with a paste-anchored MAD-scaled pop gate that handles dense clusters, fine grains on uniform paste, and mottled tempers consistently.
- Void analysis — Brightness-gated dark feature detection that separates pores from dark mineral inclusions.
- Watershed cluster recovery — Dense touching grains are split into individual sub-grains rather than being counted as one lumpy contour.
- Size and density metrics — Areas in cm², densities per cm², with the denominator computed over the actually-searched area (not the full sherd) so cross-sherd comparisons stay valid.
- Orientation and color — Per-inclusion orientation distributions and CIELAB color summaries.
- Batch processing — Run a whole folder of sherd scans into a single CSV via
full_analysis.
Installation
From source
git clone https://github.com/aleciaco/AMFOrA_public.git
cd AMFOrA_public
pip install -e .
PyPI installation is planned for the next release.
Dependencies
Python 3.10+, OpenCV, NumPy, pandas, matplotlib, SciPy, scikit-image, Pillow. All pulled in automatically by pip install.
Quickstart
import cv2
import amfora
# Load a raw scanned sherd image (background still present)
image = cv2.imread('sherd.jpg')
# One-call analysis: masking, blob + contour detection, color, orientation
results = amfora.analyze_single_sherd(image, scan_dpi=1200)
print(f"Blob inclusions: {results['blob_inclusion_count']}")
print(f"Contour inclusions: {results['contour_inclusion_count']}")
print(f"Inclusion density: {results['contour_inclusion_density_per_cm2']:.1f} per cm²")
For a batch of sherds in a folder:
df = amfora.full_analysis('path/to/sherd_scans/', scan_dpi=1200)
df.to_csv('results.csv')
See examples/ for working notebooks and docs/ for the full user guide.
Documentation
The Jupyter Book under docs/ builds locally with jupyter-book build docs/ and covers installation, quickstart, the user guide, full API reference, and tutorials. Online publishing via GitHub Pages is planned (link will go here once the site is live).
Core entry points
analyze_single_sherd(image, scan_dpi)— Mask + detect + measure a single sherd; returns a dict of metrics.full_analysis(folder_path, scan_dpi)— Runanalyze_single_sherdover a directory; returns a pandas DataFrame and writes CSV.sherd_mask(image, scan_dpi)— GrabCut-based mask isolating the sherd from scanner background.sherd_blobs(masked_image, scan_dpi)— SimpleBlobDetector with adaptive thresholds and paste-anchored pop gating.contour_detection(masked_image, scan_dpi)— Contour-based detection with watershed cluster recovery and multigrain split.
Every function has a NumPy-style docstring with parameter and return-value details.
DPI and units
All measurements are DPI-aware. The default is scan_dpi=1200. Conversion factor is dpcm = scan_dpi * 0.3937; areas are returned in cm². Set scan_dpi to match your scanner.
Scientific applications
Designed for:
- Quantitative petrographic analysis of ceramic fabrics
- Inclusion size and shape distribution studies
- Void analysis (organic burnout, shrinkage cracks)
- Orientation analysis of elongated inclusions
- Color characterization (paste, inclusion populations, core-periphery firing-atmosphere indicators)
Cross-fabric inclusion-density comparisons are limited by optical contrast: grains that share the matrix's color are invisible to scanning regardless of detection parameters. See analyze_single_sherd's docstring for the full discussion and the R08G/R08TC calibration data showing the ~2.3× density gap on bars sharing identical sand temper.
Contributing
Pull requests welcome — see CONTRIBUTING.md for development setup, code style, and PR guidelines. By participating you agree to the Code of Conduct.
Disclosure: use of generative AI tools
Parts of this package have been developed and refined with assistance from generative AI tools (Anthropic Claude, primarily for testing, repackaging in modern Python standards, docstring and documentation drafting, code review, and iterative tuning of detector parameters). All algorithmic design decisions, validation against real sherd data, and final acceptance of changes were performed by the human maintainer. As a solo archaeologist who knows Python, I had a glaring gap in my ability to actually format the github in the modern standard where it would be useful by other researchers, so I turned to Anthropic Claude to help format the documentation, make docstrings make enough sense for other users, write tests, and do linting/CI because I had never learned how to do that. If there are any issues with this content, please reach out or suggest better ways of maintaining it!
License
MIT License — see LICENSE.
Citation
If you use AMFOrA in published work, please cite:
Iacobucci, A. (2026). AMFOrA: Automated Macroscopic Fabric and Orientation Analysis for ceramic sherds. https://github.com/aleciaco/AMFOrA_public
A formal citation (DOI / Zenodo archive / JOSS paper) will be added when the package is released to PyPI.
Support
- Bug reports and feature requests: GitHub issues
- Maintainer: aleciaco@uw.edu
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file amfora-1.0.0.tar.gz.
File metadata
- Download URL: amfora-1.0.0.tar.gz
- Upload date:
- Size: 108.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56cf3e2b59b8bf1d219190dc4007a0b1e961374102f9e82369ba83b416728bd4
|
|
| MD5 |
2fe0c96fbb68cd201c74b27b3f0fa89b
|
|
| BLAKE2b-256 |
e9d8d646c4fac6d0d86bdc00f2a2a583a9727857308b47d0b2dbf8ab84e1dff0
|
Provenance
The following attestation bundles were made for amfora-1.0.0.tar.gz:
Publisher:
publish.yml on aleciaco/AMFOrA_public
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amfora-1.0.0.tar.gz -
Subject digest:
56cf3e2b59b8bf1d219190dc4007a0b1e961374102f9e82369ba83b416728bd4 - Sigstore transparency entry: 1695405222
- Sigstore integration time:
-
Permalink:
aleciaco/AMFOrA_public@fae06ae5bfd6a8cc0b6a638ec98628250fcb6e23 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/aleciaco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fae06ae5bfd6a8cc0b6a638ec98628250fcb6e23 -
Trigger Event:
push
-
Statement type:
File details
Details for the file amfora-1.0.0-py3-none-any.whl.
File metadata
- Download URL: amfora-1.0.0-py3-none-any.whl
- Upload date:
- Size: 107.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6f4440de42d808d8d1ed05532f8bb4e7fb60512ac18c94c8b806c617ac46ca6
|
|
| MD5 |
f4755a073a60575ca0f215b6c5a20a8d
|
|
| BLAKE2b-256 |
42ae9c7280daa56d42d81e8a05fbc050b6dd683b8a1ea7b39702e257386dd5a9
|
Provenance
The following attestation bundles were made for amfora-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on aleciaco/AMFOrA_public
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amfora-1.0.0-py3-none-any.whl -
Subject digest:
c6f4440de42d808d8d1ed05532f8bb4e7fb60512ac18c94c8b806c617ac46ca6 - Sigstore transparency entry: 1695405629
- Sigstore integration time:
-
Permalink:
aleciaco/AMFOrA_public@fae06ae5bfd6a8cc0b6a638ec98628250fcb6e23 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/aleciaco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fae06ae5bfd6a8cc0b6a638ec98628250fcb6e23 -
Trigger Event:
push
-
Statement type: