Implement a measure of similarity for two bool arrays and use it to measure

how close we are getting to encoding the target image.
This commit is contained in:
kris 2019-01-02 00:24:25 +00:00
parent 7c5e64fb6f
commit 8e3f8c9f6d
2 changed files with 24 additions and 12 deletions

22
main.py
View File

@ -8,7 +8,7 @@ import screen
CYCLES = 1024 * 1024
MAX_OUT = 20 * 1024
VIDEO_FPS = 30
APPLE_FPS = 10
APPLE_FPS = 5
def main():
@ -25,6 +25,7 @@ def main():
im = Image.fromarray(frame)
im = im.resize((screen.Frame.XMAX, screen.Frame.YMAX))
im = im.convert("1")
im = np.array(im)
# im.show()
f = screen.Frame(im)
@ -34,18 +35,18 @@ def main():
decoder.from_stream(iter(stream))
assert np.array_equal(decoder.screen, s.screen)
#print(" ".join("%02x(%02d)" % (b, b) for b in stream))
# print(" ".join("%02x(%02d)" % (b, b) for b in stream))
# assert that the screen decodes to the original bitmap
#bm = s.to_bitmap()
bm = s.to_bitmap()
# print(np.array(im)[0:5,0:5])
# print(bm[0:5,0:5])
#print("Comparing bitmaps")
#print(np.array(im))
#print(bm)
#print(s.screen)
#assert np.array_equal(bm, im), np.ma.masked_array(
# print("Comparing bitmaps")
# print(np.array(im))
# print(bm)
# print(s.screen)
# assert np.array_equal(bm, im), np.ma.masked_array(
# bm, np.logical_not(np.logical_xor(bm, im)))
# d = Image.fromarray(s.screen)
@ -55,7 +56,8 @@ def main():
if bytes_out > MAX_OUT:
break
print("Frame %d, %d bytes" % (idx, len(stream)))
print("Frame %d, %d bytes, similarity = %f" % (
idx, len(stream), s.similarity(im,bm)))
out.write(stream)
out.write(bytes(s.done()))

View File

@ -169,6 +169,13 @@ class Screen:
cycles_per_pixel = cycles / xor_weight
return cycles_per_pixel
@staticmethod
def similarity(a1: np.array, a2: np.array) -> float:
"""Measure bitwise % similarity between two arrays"""
bits_different = np.sum(np.logical_xor(a1, a2))
return 1 - (bits_different / (np.shape(a1)[0] * np.shape(a1)[1]))
def encoded_byte_stream(self, deltas: np.array,
target: np.array) -> Iterator[int]:
"""Emit encoded byte stream for rendering the image.
@ -201,6 +208,9 @@ class Screen:
page = 0x20
content = 0x7f
# TODO: strictly picking the highest next score might end up
# thrashing around between pages/content bytes. Maybe score over
# larger runs of bytes?
scores = []
while changes:
if not scores:
@ -227,7 +237,7 @@ class Screen:
# Invalidate scores
# TODO: we don't need to invalidate all of them, just those
# for the current page
# for the old and new page
scores = []
if new_content != content:
@ -237,7 +247,7 @@ class Screen:
# Invalidate scores
# TODO: we don't need to invalidate all of them, just those
# for the current page
# for the old and new content byte
scores = []
self._write(page << 8 | offset, content)