Stupid Puzzle box
The space was sent a cool puzzle box as part of a secret santa. One of the puzzles involves getting the output of a flashing light into an LDR on the other side of the box. I played with this with another member last week, we decided to try and decode the light output.
I am sure we don't need to do this, but I wanted to try out my idea. He tried to use FinalCut to process a vide of the output, but this didn't work. I suggested we try breaking the video down to frames, running a brightness threshold over them, then generating a plot of the output.
Turn the video into frames:
$ ffmpeg -i VID.mp4 -f image2 frames/image-%07d.png
We can use
convert
from
imagemagick
to threshhold an image, here we
convert
its colour space into hue saturation and brightness and resize the
image down to 1x1. Convert will give a text description of what it did so we
don't have loads of temporary images.
I hand picked a 'dark' image:
$ convert dark.png -colorspace hsb -resize 1x1 txt:-
# ImageMagick pixel enumeration: 1,1,65535,hsb
0,0: (10086,47272,7376) #27B81D hsb(55,72%,11%)
And a 'light' image:
$ convert light.png -colorspace hsb -resize 1x1 txt:-
# ImageMagick pixel enumeration: 1,1,65535,hsb
0,0: (32525,17838,41551) #7F45A2 hsb(179,27%,63%)
I ran
convert
over each file with some
awk
magic:
for filename in frames/*png; do
echo $filename
convert $filename -colorspace hsb -resize 1x1 txt:- | tail -n 1 | awk '{ print $4}' | awk -F "," '{ print $3}' | sed -e "s/%)//" >> outfile
done
I ran the outputfile through matplotlib to generate a nice plot of the light values.
import matplotlib.pyplot as plt
values = []
with open("outfile", "r") as f:
for line in f.readlines():
value = int(line)
if value > 40:
value = 100
else:
value = 10
values.append(value)
plt.figure(figsize=(30,2))
plt.plot(values)
plt.ylabel('brightness')
plt.savefig("plot.png")
The hardest part of this was getting the video off my phone, the most time consuming was installing matplotlib.
Reading: Normal