blob: 9803d533179275a1698a10f7a8bd6b688ebca385 [file] [log] [blame]
#!/usr/bin/env python
# prithreshpng
# Threshold one image against another.
# Output a 1-bit per channel PNG, where l <= r
import collections
from array import array
import png
"""
prithreshpng file1.png file2.png
The `prithreshpng` tool compares channels from the input images.
"""
Image = collections.namedtuple("Image", "rows info")
class Error(Exception):
pass
class ImageError(Error):
pass
def thresh(out, args):
"""Compare input PNG files and threshold the right image
against the left;
the output image is 1 when l <= r, that is when the right
image is at least as bright as the left.
"""
paths = args.input
if len(paths) != 2:
raise Error("Required input is missing.")
images = []
for image_index, path in enumerate(paths):
inp = png.cli_open(path)
rows, info = png.Reader(file=inp).asDirect()[2:]
rows = list(rows)
image = Image(rows, info)
images.append(image)
planes = images[0].info["planes"]
size = images[0].info["size"]
for image in images:
if image.info["planes"] != planes:
raise ImageError("All images should have same number of channels")
if image.info["size"] != size:
raise ImageError("All images should have same size")
size = images[0].info["size"]
out_channels = planes
# Values per row, of output image
vpr = out_channels * size[0]
def thresh_row_iter():
"""
Yield each woven row in turn.
"""
# The zip call creates an iterator that yields
# a tuple with each element containing the next row
# for each of the input images.
for row_tuple in zip(*(image.rows for image in images)):
# Compare values pairwise
vs = zip(*row_tuple)
# output row
row = array("B", [v[0] <= v[1] for v in vs])
yield row
w = png.Writer(
size[0],
size[1],
greyscale=True,
alpha=False,
bitdepth=1,
)
w.write(out, thresh_row_iter())
def main(argv=None):
import argparse
import itertools
import sys
if argv is None:
argv = sys.argv
argv = argv[1:]
parser = argparse.ArgumentParser()
parser.add_argument("input", nargs=2)
args = parser.parse_args(argv)
return thresh(png.binary_stdout(), args)
if __name__ == "__main__":
main()