Anyone who knows Arkwood, my Belgian chum, will tell you that he is a sexist pig. So it came as no surprise when he told me, ‘I have a ticket to a fashion show. Just think of all those lovely models in their bikinis.’ He was rubbing his groin again.
The only problem is, Arkwood can’t wolf whistle to save himself. ‘How am I going to let the pretty girls know I like their booty?’ he cried. I suggested that he clap his hands like any normal person. But my advice did not go down well. Arkwood burst into an uncontrollable sob.
‘Okay,’ I relented, ‘I will write some Python code on my tiny Raspberry Pi computer. It will use a webcam to detect when an object is moving – namely the catwalk model – and then play a wolf whistle through a speaker.’
Here’s the gear Arkwood will need to ply himself with. First up, the Raspberry Pi computer and a portable power supply, which he can stuff into his jacket pocket:
Next, the webcam, which will take regular snaps of the catwalk:
And finally the speaker, which will play the sound of a wolf whistle:
The webcam can be taped to one of the shoulders on Arkwood’s jacket. The speaker can be taped to the other shoulder.
So here’s a rather poor illustration of Arkwood at the fashion show, with all the equipment wired up:
So let’s write the code that is going to run on our Raspberry Pi computer:
import cv2 import pygame from webcam import Webcam # constants HISTORY = 12 SAMPLE_RATE = 5 THRESHOLD = 2000 # variables sample_counter = 0 # set up webcam webcam = Webcam() webcam.start() # set up wolf whistle pygame.mixer.init() wolfwhistle = pygame.mixer.Sound("77753__benboncan__wolfwhistle.wav") # set up background subtraction fgbg = cv2.BackgroundSubtractorMOG() while True: # take a snap of the catwalk photo = webcam.get_current_frame() # apply background subtraction fgmask = fgbg.apply(photo, learningRate=1.0/HISTORY) # use a sample rate if sample_counter % SAMPLE_RATE == 0: # if object detected if cv2.countNonZero(fgmask) > THRESHOLD: # play wolf whistle through speakers wolfwhistle.play() # increment counter sample_counter += 1
To begin with, we need to define some constants and initialize our webcam and wolf whistle.
Before entering a while loop, we set up OpenCV Background Subtraction. We are going to use background subtraction to detect moving objects.
Once in our while loop, we capture a photograph from the webcam attached to the Raspberry Pi. Background subtraction then uses the photo to detect object movement.
Now, we don’t want to play a wolf whistle after every webcam snap. For a start, the time it takes to whistle would adversely affect the background subtraction calculation. So instead, I’ve introduced a sample rate on every 5th photo captured.
We inspect each 5th photo, using cv2.countNonZero, to determine how many white pixels are in the photo. If the number of white pixels is greater than our threshold of 2000 then we play a wolf whistle sound using Pygame.
So you’re probably wondering what white pixels have to do with it. Well, background subtraction outputs a mask of our photograph. The mask will show object movement using white pixels, while the rest of the mask will be in black. So if our webcam captures a model striding up the catwalk, then we can expect lots of white pixels. And it will trigger a wolf whistle sound through the speaker attached to our Pi.
Let’s have a demo, to make sure that the program is working before Arkwood wears the technology to the fashion show. Here’s a catwalk with a model on it (well, a shoe box with a wind-up robot on it):
And here’s the background subtraction mask created when the model strides up the catwalk:
All those white pixels in the mask have triggered our wolf whistle, which plays out through the speaker. Fantastic!
The day had arrived. I put the Raspberry Pi and power supply into Arkwood’s tweed jacket pocket. I taped the webcam to his left shoulder, and taped the speaker to his right shoulder. The Python program was running. All that was left to do was switch on the speaker once he positioned himself in front of the catwalk. As soon as the models start parading up and down, his wolf whistles will fill the air.
As Arkwood left, he turned to me and said, ‘Don’t wait up for me! I expect to be in a playboy mansion tonight, in a silk-dressed bed with a bounty of bikini-clad models!’
Yet, within an hour Arkwood returned to the house with a bloody nose. ‘Did the models not appreciate your wolf whistles then?’ I mocked. But, as it turned out, he did not even get to the fashion show. The silly idiot had fiddled with the speaker whilst passing a building site, emitting unwelcome wolf whistles to the labourers. They set upon him like a pack of dogs.
I sourced the wolf whistle from Freesound:
And here’s the Webcam class, which takes snaps of the catwalk:
import cv2 from threading import Thread class Webcam: def __init__(self): self.video_capture = cv2.VideoCapture(0) self.current_frame = self.video_capture.read() # create thread for capturing images def start(self): Thread(target=self._update_frame, args=()).start() def _update_frame(self): while(True): self.current_frame = self.video_capture.read() # get the current frame def get_current_frame(self): return self.current_frame
Final word to Kraftwerk