03 April 2020

Heart rate from video

I knew about heartbeat sensors that use light, and I have seen Android applications that use your phone’s camera to measure your heart rate.


  • Blood absorbs light, and the amount of light that gets absorbed/reflected depends on the amount of blood in the area.
  • When your heart beats, the amount of blood in your finger changes, and so does the amount of light that gets absorbed/reflected.
  • A camera with the flash on can detect these changes in light if you put your finger on the camera.


I didn’t need to do this live, so I just recorded a video of my finger on the camera using my phone. I then wrote a quick Python script to run the video through ffmpeg to iterate over each frame as an image.

I used the average pixel lightness as a measure of the amount of light that gets absorbed/reflected. When I plotted this value over time, it looked very obviously like a heartbeat. Like a very typical heartbeat, you can’t miss it.

This was underwhelmingly easy. Perhaps a future project could be to do post-process this data with some filters, or to do it live.

17 April 2020

Collecting Style 12 chess data

Style 12 is a data format used by Internet Chess Servers and clients to exchange information about chess games.

I have a page about Style 12 on my wiki.

The protocol for connecting to an Internet Chess Server is relatively simple. It is a text-based protocol. It looks like it was designed to be used by humans rather than computers, but things like Style 12 try to make it easier for computers to parse the data.

The Python code I used to collect the data is given below.

import socket

full = False

s = socket.socket()
s.connect(("freechess.org", 5000))

# Not Full: Removing game 166 from observation list.
# Full: You are already observing the maximum number of games.

f = s.makefile('rwb')


for line in f:
    line = line.strip()
    if line.startswith(b'Press return to enter the server'):

f.write(b'set style 12\n')

with open('style12.txt', 'a+') as logfile:
    for line in f:
        line = line.strip()
        if b'Removing game' in line and b'from observation list.' in line:
            full = False
        if b'You are already observing the maximum number of games.' in line:
            full = True
        if not full:
            f.write(b"observe *\r\n")
        if line.startswith(b'<12>'):