doritex
Finds the words in an image and the direction each one reads, for text rotated at any angle. Runs on netcl, on an OpenCL GPU or on the CPU. The model weights are included.
pip install doritex
Example
from PIL import Image, ImageDraw, ImageFont
import doritex
# "Hello World", upside down
img = Image.new("RGB", (640, 200), "white")
ImageDraw.Draw(img).text((40, 60), "Hello World", fill="black", font=ImageFont.load_default(size=40))
img = img.rotate(180)
det = doritex.load()
words = det.detect(img)
for w in words:
print(f"angle {w.angle360:5.1f}° score {w.score:.2f} direction {w.direction_confidence:.2f} starts at {w.quad[0].round()}")
upright = img.rotate(words[0].rotation_to_upright, expand=True) # now reads left to right
doritex.draw(img, words).save("words.png") # boxes + arrows along the reading direction
print(det.crop(img, words[0]).shape) # first word cut out upright
Output:
angle 180.1° score 0.85 direction 1.00 starts at [602. 83.]
angle 181.4° score 0.81 direction 0.99 starts at [500. 83.]
(64, 95, 3)
Both words were found upside down (about 180°). They are listed most confident first. Each starts where its first letter is: "Hello" at the right, "World" further left.
Reading direction and angles
The reading direction runs from a word's first letter to its last. doritex reports it on every word:
quad[0] → quad[1]points along the reading direction (start → end of the baseline).angle360gives that direction as a total angle, counter-clockwise from normal text:0°reads left to right,90°bottom to top,180°upside down,270°top to bottom. Text tilted on a disc or a photo gets an in-between value.angleis the same rotation in the range −180…180.rotation_to_uprightis how far to rotate the image so that the word reads normally. It uses the convention ofPIL.Image.rotate:img.rotate(word.rotation_to_upright, expand=True).direction_confidence(0.5–1) says how sure the model is that the word is not actually reversed, i.e. rotated by 180°. Values near 0.5 mean the glyphs did not show it. This happens with tiny text, and with tokens that also read upside down (SOS,6/9).
API
doritex.load(weights=None, device="auto", input_size=1024) -> Detector
Loads the bundled model. device is "auto" (an OpenCL GPU if present) or "cpu". Images larger than
input_size on their long side are scaled down; smaller images are used at full resolution.
Detector.detect(image, input_size=None, score_threshold=0.3, nms_iou=0.4) -> list[Word]
image can be a file path, a PIL.Image or a numpy array (RGB, RGBA or grayscale; uint8, or float in 0–1).
Coordinates are in pixels of that image.
Detector.crop(image, word, height=64) -> np.ndarray
Cuts the word out and turns it upright (RGB uint8), for example as input for OCR.
doritex.draw(image, words) -> PIL.Image
Draws each box and an arrow along the reading direction: green when the direction is confident, orange when it is
not.
Word
| attribute | meaning |
|---|---|
quad |
4 corners (4, 2): start of the baseline, end of the baseline, end of the top line, start of the top line |
angle360, angle |
reading direction as an angle, counter-clockwise: 0…360 and −180…180 |
direction |
unit vector of the reading direction (image coordinates, y points down) |
rotation_to_upright |
degrees to pass to PIL.Image.rotate to make the word upright |
score |
detection confidence, 0–1 |
direction_confidence |
confidence in the reading direction, 0.5–1 |
center, width, height, bbox |
centre, length along and across the text, axis-aligned box (x0, y0, x1, y1) |
Notes
Words are found best at about 7–70 px height. Lower input_size for images with very large text.
License
MIT
Metadata
Release files for doritex 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| doritex-0.1.0.tar.gz | 4.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| doritex-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 8.2 MB
Release files / doritex-0.1.0.tar.gz
| Download URL | doritex-0.1.0.tar.gz |
|---|---|
| Size | 4.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d100830dc87f5c04f91817e4bb6ecfa0404f82207594a1e049cc7f5316b8784e
|
|
BLAKE2b-256 checksum How to use checksums |
3d0c523a0310df93e83959dc190c676629c97be19f0f572ff1ae253c22ba13e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / doritex-0.1.0-py3-none-any.whl
| Download URL | doritex-0.1.0-py3-none-any.whl |
|---|---|
| Size | 4.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3ee043d251986d7f2b7fb2f210df09b4246e9ebdf8e83d416b23be884706520d
|
|
BLAKE2b-256 checksum How to use checksums |
1db4ce66146ab61bfa07e03c4c12fa9d2bff91cfecce2558cadca9e5c825f037
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|