QR Codes and the Game of Life

(0 comments)

The following code identifies a QR code in a provided image and plays John Conway's Game of Life with it. It uses OpenCV (for image recognition and QR code detection), along with SciPy, NumPy and Matplotlib. If you don't have them, they can be installed with

pip install opencv-python
pip install numpy
pip install scipy
pip install matplotlib

To use the script, run it from the command line with, e.g.

$ python qrlife.py qr-photo.jpg

A sample photo of a QR code is: qr-photo.jpg.

import sys
import cv2
import numpy as np
from scipy.signal import convolve2d
import matplotlib.pyplot as plt
from matplotlib import animation

class Life:
    """A Game of Life simulator."""

    def __init__(self, arr, pad=25):
        """Initialize the instance.

        The provided array consists of zero and non-zero entries,
        representing dead and alive cells, respectively. It is optionally
        padded by width pad on all sides with zeros.

        """

        # Set the "world" array as boolean and initialize the figure.
        # The world is depicted as a black-and-white array of squares.
        self.arr = arr.astype(bool)
        self.arr = np.pad(self.arr, pad)

        self.fig, self.ax = plt.subplots()
        self.im = self.ax.imshow(self.arr, cmap=plt.cm.binary,
                                 interpolation='nearest')
        # Remove the Axes tick marks.
        self.ax.set_xticks([])
        self.ax.set_yticks([])

    def do_step(self):
        """Advance the Game of Life world by one generation."""

        # Use convolution method to count neighbours, e.g.
        # http://jakevdp.github.io/blog/2013/08/07/conways-game-of-life/
        nn = convolve2d(self.arr, np.ones((3, 3)), mode='same',
                        boundary='wrap') - self.arr
        self.arr = (nn == 3) | (self.arr & (nn == 2))

    def init_animation(self):
        """Initialize the animation: self.im is updated on each time step."""

        self.im.set_data(np.zeros_like(self.arr))
        return self.im,

    def animate(self, i):
        """Draw the current state of the world and advance by one time step."""

        self.im.set_data(self.arr)
        self.do_step()

    def play(self, frames=1000, interval=100):
        """Play the Game of Life, depicted as a Matplotlib animation."""

        anim = animation.FuncAnimation(self.fig, self.animate,
                    init_func=self.init_animation, frames=frames,
                    interval=interval)
        # If we're saving the animation as a video, uncomment these two lines.
        #writer = animation.FFMpegWriter(fps=4)
        #anim.save('life.mp4', writer=writer)

        # If we're just viewing the animation locally, uncomment this line.
        plt.show()

if __name__ == "__main__":
    # Read the image filename from the command line and detect the QR code.
    qr_image = sys.argv[1]
    image = cv2.imread(qr_image)
    detector = cv2.QRCodeDetector()
    value, points, arr = detector.detectAndDecode(image)
    # Print the "value" of the QR code (e.g. the URL it encodes).
    print(f'QR code with dimensions {arr.shape} detected.')
    print('QR value:', value)

    life = Life(arr)
    life.play()
Current rating: 5

Comments

Comments are pre-moderated. Please be patient and your comment will appear soon.

There are currently no comments

New Comment

required

required (not published)

optional

required