Allow 1 mode images in apply() and match()

This commit is contained in:
Andrew Murray 2025-12-23 14:13:51 +11:00
parent 9b7200d2b4
commit a704711404
3 changed files with 22 additions and 24 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 B

After

Width:  |  Height:  |  Size: 79 B

View File

@ -15,13 +15,10 @@ def string_to_img(image_string: str) -> Image.Image:
rows = [s for s in image_string.replace(" ", "").split("\n") if len(s)]
height = len(rows)
width = len(rows[0])
im = Image.new("L", (width, height))
for i in range(width):
for j in range(height):
c = rows[j][i]
v = c in "X1"
im.putpixel((i, j), v)
im = Image.new("1", (width, height))
for x in range(width):
for y in range(height):
im.putpixel((x, y), rows[y][x] in "X1")
return im
@ -42,10 +39,10 @@ def img_to_string(im: Image.Image) -> str:
"""Turn a (small) binary image into a string representation"""
chars = ".1"
result = []
for r in range(im.height):
for y in range(im.height):
line = ""
for c in range(im.width):
value = im.getpixel((c, r))
for x in range(im.width):
value = im.getpixel((x, y))
assert not isinstance(value, tuple)
assert value is not None
line += chars[value > 0]
@ -165,10 +162,12 @@ def test_edge() -> None:
)
def test_corner() -> None:
@pytest.mark.parametrize("mode", ("1", "L"))
def test_corner(mode: str) -> None:
# Create a corner detector pattern
mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "4:(00. 01. ...)->1"])
count, Aout = mop.apply(A)
image = A.convert(mode) if mode == "L" else A
count, Aout = mop.apply(image)
assert count == 5
assert_img_equal_img_string(
Aout,
@ -184,14 +183,13 @@ def test_corner() -> None:
)
# Test the coordinate counting with the same operator
coords = mop.match(A)
coords = mop.match(image)
assert len(coords) == 4
assert tuple(coords) == ((2, 2), (4, 2), (2, 4), (4, 4))
for image in (Aout, Aout.convert("1")):
coords = mop.get_on_pixels(image)
assert len(coords) == 4
assert tuple(coords) == ((2, 2), (4, 2), (2, 4), (4, 4))
coords = mop.get_on_pixels(Aout)
assert len(coords) == 4
assert tuple(coords) == ((2, 2), (4, 2), (2, 4), (4, 4))
def test_mirroring() -> None:
@ -233,12 +231,12 @@ def test_negate() -> None:
def test_incorrect_mode() -> None:
im = hopper("RGB")
im = hopper()
mop = ImageMorph.MorphOp(op_name="erosion8")
with pytest.raises(ValueError, match="Image mode must be L"):
with pytest.raises(ValueError, match="Image mode must be 1 or L"):
mop.apply(im)
with pytest.raises(ValueError, match="Image mode must be L"):
with pytest.raises(ValueError, match="Image mode must be 1 or L"):
mop.match(im)
with pytest.raises(ValueError, match="Image mode must be 1 or L"):
mop.get_on_pixels(im)

View File

@ -209,8 +209,8 @@ class MorphOp:
msg = "No operator loaded"
raise Exception(msg)
if image.mode != "L":
msg = "Image mode must be L"
if image.mode not in ("1", "L"):
msg = "Image mode must be 1 or L"
raise ValueError(msg)
outimage = Image.new(image.mode, image.size, None)
count = _imagingmorph.apply(bytes(self.lut), image.getim(), outimage.getim())
@ -226,8 +226,8 @@ class MorphOp:
msg = "No operator loaded"
raise Exception(msg)
if image.mode != "L":
msg = "Image mode must be L"
if image.mode not in ("1", "L"):
msg = "Image mode must be 1 or L"
raise ValueError(msg)
return _imagingmorph.match(bytes(self.lut), image.getim())