Lego detection using OpenCV (Mark III)

Tags

, , , , , , , , , , , ,

Arkwood, my scruffy Belgian buddy, was convinced that Lego policemen were watching him, waiting to arrest him for smoking marijuana. ‘They’re over by the plant pots!’ he shrieked, ‘I can’t even light up a joint without fear of being banged up.’ In order to relieve his addled brain, I created some Python code on my Raspberry Pi computer that detected Lego policemen through a webcam. A siren sound would play through some speakers, informing my chum to stub out his spliff before the long arm of the law tapped him on the shoulder. The crisis was over. Or so I thought…

But today, Arkwood’s sweaty face told me, ‘What if the cops are somewhere else in the room? They could be at the side of the chesterfield, or under the bureau plat!’

‘Don’t worry,’ I replied somewhat exasperated, ‘I will fix my Raspberry Pi atop your radio controlled car, so you can steer it about the lounge.’

Okay, so here is the radio controlled car:

lego_jeep

And here is my tiny Raspberry Pi computer:

lego_pi

Now, in order to provide juice to my Pi, I have employed the following portable power supply:

lego_power

I have no idea whether a battery charger for an iPhone provides the correct power supply to my computer. Perhaps it will fry the chips, or corrupt the SD card? But what the hell, it works, and I prefer to live life on the sheer edge of a cliff face.

Next up, I need a webcam. I will stick it on the bonnet of the car so as to spy on the pigs respected local constabulary:

lego_webcam

And a speaker, which will play the siren sound if a Lego policeman has been detected:

lego_speaker

Cool. So here is the radio controlled car, fully equipped and ready for patrol:

lego_jeep_equipped_1

lego_jeep_equipped_2

All that is left to do is to hand over the controller to Arkwood. Here is the car in action, finding a Lego policeman behind some shrub:

lego_jeep_action

We can see from the snap taken by our mounted webcam that the policeman has been successfully detected. The siren sounds and Arkwood extinguishes his ganja:

lego_policeman_detected

‘Thank God for that!’ my buddy exclaimed, ‘I won’t have to spend the night in a prison cell.’

We settled down to watch Strictly Come Dancing, me with my rum and ginger beer, he with his contraband herbs. Puffing away, he twiddled the knobs of the controller and the car swept the carpet for any trace of the fuzz. Suddenly, an almighty siren sounded. The ear-piercing noise caused me to spill alcohol down my blouse and Arkwood to drop his roll-up on his lap, setting fire to his groin.

‘Shit!’ I shrieked, ‘I need to turn the volume down on the speakers.’

Arkwood was still flapping about, his hand desperately brushing hot ash off his trousers. I threw some of my rum onto his genitals, to douse the embers.

P.S.

Here’s the Python code for detecting Lego policemen:

from webcam import Webcam
from detection import Detection
import pygame
from time import sleep

# set up webcam
webcam = Webcam()
webcam.start()

#set up detection
detection = Detection()

# set up siren
pygame.mixer.init()
siren = pygame.mixer.Sound("221562__alaskarobotics__european-police-siren-1.wav")

# attempt to detect lego policeman
while True:

    image = webcam.get_current_frame()
    item_detected = detection.is_item_detected_in_image('haarcascade_lego_policeman.xml', image)

    if item_detected:
        siren.play()

    sleep(2)

First we set up our webcam and detection system, before using Pygame to hook up a siren sound. After that, we simply loop the program, attempting to detect Lego policemen in the latest webcam image, and playing the siren if any are found.

Here’s the Webcam class, which utilises a thread to get the latest image:

import cv2
from threading import Thread

class Webcam:

    def __init__(self):
        self.video_capture = cv2.VideoCapture(0)
        self.current_frame = self.video_capture.read()[1]
        
    # 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()[1]
                
    # get the current frame
    def get_current_frame(self):
        return self.current_frame

And the Detection class, which uses the OpenCV haar casscade classifier file I created in my previous post to detect Lego policemen in images:

import cv2
from datetime import datetime

class Detection(object):
 
    # is item detected in image
    def is_item_detected_in_image(self, item_cascade_path, image):

        # do detection
        item_cascade = cv2.CascadeClassifier(item_cascade_path)
        gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        items = item_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=36)

        for (x,y,w,h) in items:
            cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
        
        # save image to disk
        self._save_image(image)
              
        # indicate whether item detected in image
        return len(items) > 0

    # save image to disk
    def _save_image(self, img):
        filename = datetime.now().strftime('%Y%m%d_%Hh%Mm%Ss%f') + '.jpg'
        cv2.imwrite("WebCam/Detection/" + filename, img)
Follow

Get every new post delivered to your Inbox.

Join 64 other followers