Skip to content

Commit

Permalink
[WIP] Test and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
PonteIneptique committed Oct 1, 2024
1 parent b371780 commit ac47772
Show file tree
Hide file tree
Showing 23 changed files with 12,769 additions and 112 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Test

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Display Python version
run: python -c "import sys; print(sys.version)"
- name: Install dependencies
run: |
pip install -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu
pip install pytest pytest-cov coveralls pytest-sugar
- name: Run Tests
run: |
pytest --doctest-modules --cov=yaltai --verbose
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Convert (and split optionally) your data
```bash
# Keeps .1 data in the validation set and convert all alto into YOLOv5 format
# Keeps the segmonto information up to the regions
yaltai alto-to-yolo PATH/TO/ALTOorPAGE/*.xml my-dataset --shuffle .1 --segmonto region
yaltai convert alto-to-yolo PATH/TO/ALTOorPAGE/*.xml my-dataset --shuffle .1 --segmonto region
```

And then [train YOLO](https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def run(self):
# py_modules=['mypackage'],

entry_points={
'console_scripts': ['yaltai=yaltai.yaltai:cli', 'kraken-yaltai=yaltai.kraken_yaltai:cli'],
'console_scripts': ['yaltai=yaltai.cli.yaltai:yaltai_cli'],
},
install_requires=REQUIRED,
extras_require=EXTRAS,
Expand Down
Empty file added tests/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions tests/nano-yolo-ladas.pt
Git LFS file not shown
40 changes: 40 additions & 0 deletions tests/test_convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import tempfile
import os
from click.testing import CliRunner

from yaltai.cli.yaltai import yaltai_cli


def test_yaltai_single_alto_to_xml():
"""Ensures that we can convert to YOLO format"""
runner = CliRunner()

with tempfile.TemporaryDirectory() as tempdir:
# Run the Click command
result = runner.invoke(
yaltai_cli,
[
"convert",
"alto-to-yolo",
os.path.join(os.path.abspath(os.path.dirname(__file__)), "test_files", "alto_dataset", "output.xml"),
tempdir,
])

# Ensure the command ran successfully
assert result.exit_code == 0
assert "Found 1 to convert." in result.output
assert "- 00001 NumberingZone" in result.output, "Correct number of zone types are found"
assert "- 00001 RunningTitleZone" in result.output, "Correct number of zone types are found"
assert "- 00001 MainZone-P-Continued" in result.output, "Correct number of zone types are found"
assert "- 00004 MainZone-P" in result.output, "Correct number of zone types are found"
with open(os.path.join(tempdir, "labels", "output.txt")) as f:
data = [line.split() for line in f.read().split("\n")]
assert data == [
['0', '0.345606', '0.117500', '0.037501', '0.020206'],
['1', '0.612827', '0.118333', '0.212882', '0.020736'],
['2', '0.616390', '0.210833', '0.578172', '0.142851'],
['3', '0.616390', '0.365833', '0.577029', '0.162800'],
['3', '0.616390', '0.547500', '0.574365', '0.199581'],
['3', '0.616390', '0.727500', '0.576050', '0.161861'],
['3', '0.611639', '0.819167', '0.583077', '0.022773']
]
1 change: 1 addition & 0 deletions tests/test_files/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
page1.xml
Binary file added tests/test_files/alto_dataset/output.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12,430 changes: 12,430 additions & 0 deletions tests/test_files/alto_dataset/output.xml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions tests/test_files/annot1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
14 0.49139869729173813 0.3715823573386494 0.6673020226259856 0.07884874158983304
14 0.49408639012684263 0.23613506105158236 0.6722831676379842 0.15367804634936458
35 0.49086047308878983 0.1285771243458759 0.26186150154268084 0.03464490406179915
31 0.8086732944806309 0.13971592324943932 0.03529310935893041 0.03310740094692251
14 0.49913952691121016 0.594151507600299 0.6766986630099417 0.31005232992773485
14 0.507857387727117 0.8290804884126588 0.6902228316763799 0.1168950909543982
1 0.9231984916009598 0.4728781460254174 0.1535995886184436 0.18793919760777475
6 changes: 6 additions & 0 deletions tests/test_files/annot2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
23 0.4914115952466691 0.45760844079718643 0.6449045732805185 0.4102297772567409
23 0.4933705437522506 0.7764806565064478 0.6465250270075622 0.2320398593200469
31 0.7885343896290963 0.11840562719812427 0.033172488296723084 0.026182883939038688
35 0.4834569679510263 0.1191535756154748 0.4334101548433561 0.024438452520515828
24 0.48678790061217136 0.20451113716295427 0.6372740367302845 0.10247831184056272
28 0.47840835433921497 0.14436342321219228 0.24528628015844436 0.025828839390386868
4 changes: 4 additions & 0 deletions tests/test_files/label_map.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Class0
Class1

Stuff
Binary file added tests/test_files/page1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions tests/test_kraken.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import os
import logging
import pytest
from click.testing import CliRunner
from ultralytics.utils import LOGGER
from yaltai.cli.yaltai import yaltai_cli
from kraken.lib.xml import XMLPage


@pytest.fixture(scope='function')
def custom_logger():
class CustomLoggingHandler(logging.Handler):
def __init__(self):
super().__init__()
# A list to store log records (level and message)
self.records = []

def emit(self, record):
# Append a tuple of the log level and the message to the records list
self.records.append((record.levelname, record.getMessage()))

def clear(self):
self.records = []

# Create a logger
logger = LOGGER
logger.setLevel(logging.DEBUG) # Set the logger to handle all log levels

# Create and add the custom handler to the logger
custom_handler = CustomLoggingHandler()
logger.addHandler(custom_handler)

# Clear the records list before each test
custom_handler.records.clear()

# Provide both the logger and handler for access during tests
yield custom_handler

custom_handler.records.clear()

# Optional: Remove the handler after the test to prevent interference
logger.removeHandler(custom_handler)


def test_yaltai_single_alto_to_xml(custom_logger):
"""Ensures that we can convert to YOLO format"""
runner = CliRunner()

# Trigger a warning.
result = runner.invoke(
yaltai_cli,
[
"kraken",
"--alto",
"-i",
os.path.join(os.path.abspath(os.path.dirname(__file__)), "test_files", "page1.jpg"),
os.path.join(os.path.abspath(os.path.dirname(__file__)), "test_files", "page1.xml"),
"segment",
"-y",
os.path.join(os.path.abspath(os.path.dirname(__file__)), "nano-yolo-ladas.pt")
]
)
print(result.output)
assert result.exit_code == 0
assert "page1.jpg: 640x352 2 GraphicZones, 1 MainZone-P-Continued, 1 MainZone-Sp, 2 QuireMarksZones" in "\n".join([
record[1]
for record in custom_logger.records
])

page = XMLPage(os.path.join(os.path.abspath(os.path.dirname(__file__)), "test_files", "page1.xml"))
assert {
region_type: [region.boundary for region in regions]
for region_type, regions in page.regions.items()
} == {
'GraphicZone': [[(614.0, 12.0),
(2614.0, 12.0),
(2614.0, 819.0),
(614.0, 819.0),
(614.0, 12.0)],
[(720.0, 0.0),
(2634.0, 0.0),
(2634.0, 343.0),
(720.0, 343.0),
(720.0, 0.0)]],
'MainZone-P-Continued': [[(122.0, 1536.0),
(2218.0, 1536.0),
(2218.0, 2888.0),
(122.0, 2888.0),
(122.0, 1536.0)]],
'MainZone-Sp': [[(95.0, 2974.0),
(2201.0, 2974.0),
(2201.0, 4854.0),
(95.0, 4854.0),
(95.0, 2974.0)]],
'QuireMarksZone': [[(1617.0, 4877.0),
(1825.0, 4877.0),
(1825.0, 4980.0),
(1617.0, 4980.0),
(1617.0, 4877.0)],
[(1531.0, 4841.0),
(1814.0, 4841.0),
(1814.0, 4983.0),
(1531.0, 4983.0),
(1531.0, 4841.0)]]
}

assert len([line.baseline for line in page.lines.values()])
# ToDo: Add a test to check for line being part of regions
60 changes: 60 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import os
import numpy as np
from yaltai.utils import read_labelmap, parse_box_labels, XYXY


def test_read_labelmap():
"""Asserts that reading a label map works"""
labels = read_labelmap(os.path.join(
os.path.dirname(__file__),
"test_files",
"label_map.txt"
))
assert labels == ["Class0", "Class1", "Stuff"]


def test_read_files():
"""Asserts that parsing COCO/YOLO formats work"""
annots, arrays = parse_box_labels([
os.path.join(
os.path.dirname(__file__),
"test_files",
"annot1.txt"
),
os.path.join(
os.path.dirname(__file__),
"test_files",
"annot2.txt"
)
])
assert annots == {
'boxes': [
XYXY(x0=15, y0=33, x1=82, y1=41),
XYXY(x0=15, y0=15, x1=83, y1=31),
XYXY(x0=35, y0=11, x1=62, y1=14),
XYXY(x0=79, y0=12, x1=82, y1=15),
XYXY(x0=16, y0=43, x1=83, y1=74),
XYXY(x0=16, y0=77, x1=85, y1=88),
XYXY(x0=84, y0=37, x1=99, y1=56),
XYXY(x0=16, y0=25, x1=81, y1=66),
XYXY(x0=17, y0=66, x1=81, y1=89),
XYXY(x0=77, y0=10, x1=80, y1=13),
XYXY(x0=26, y0=10, x1=70, y1=13),
XYXY(x0=16, y0=15, x1=80, y1=25),
XYXY(x0=35, y0=13, x1=60, y1=15)
],
'labels': [14, 14, 35, 31, 14, 14, 1, 23, 23, 31, 35, 24, 28]
}
assert (arrays[0] == np.array([[15, 33, 82, 41, 14, 0, 0],
[15, 15, 83, 31, 14, 0, 0],
[35, 11, 62, 14, 35, 0, 0],
[79, 12, 82, 15, 31, 0, 0],
[16, 43, 83, 74, 14, 0, 0],
[16, 77, 85, 88, 14, 0, 0],
[84, 37, 99, 56, 1, 0, 0]])).all()
assert (arrays[1] == np.array([[16, 25, 81, 66, 23, 0, 0],
[17, 66, 81, 89, 23, 0, 0],
[77, 10, 80, 13, 31, 0, 0],
[26, 10, 70, 13, 35, 0, 0],
[16, 15, 80, 25, 24, 0, 0],
[35, 13, 60, 15, 28, 0, 0]])).all()
Empty file added yaltai/cli/__init__.py
Empty file.
Loading

0 comments on commit ac47772

Please sign in to comment.