neerbasu
neerbasu

Reputation: 63

Detecting Red and Blue Squares (beanbags) using Python and CV2

I am new to CV2 and I am looking for some high level guidance for an application. I am working on a program that can detect red and blue beanbags that are in the frame of the camera. I played around with the example code offered by openCV to detect blue colors and modified it slightly to detect red as well.

import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

cap = cv2.VideoCapture(0)

while(1):

    # Take each frame
    _, frame = cap.read()

    # Convert BGR to HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # define range of blue color in HSV
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    lower_red = np.array([-20, 100, 100])
    upper_red = np.array([13, 255, 255])

    # Threshold the HSV image to get only blue colors
    mask = cv2.inRange(hsv, lower_red, upper_red)

    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(frame,frame, mask= mask)

    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()

This is (slightly modified) copied and pasted code from the OpenCV site. I am looking for the correct way to analyze the res numpy array of the dimensions <460, 640, 3> in order to detect that

  1. I have red/blue objects(s) on my screen
  2. Do something with this information such as print(1 red and 2 blue squares detected)

Image link: Input, res and mask image of blue beanbag

Upvotes: 1

Views: 1988

Answers (1)

ZdaR
ZdaR

Reputation: 22954

You will need to obtain two masks, one for red and the other for blue as:

mask_red = cv2.inRange(hsv, lower_red, upper_red)
mask_blue = cv2.inRange(hsv, lower_blue, upper_blue)

Now let's define a function which detects if given area in mask if above threshold for taking decision if the bean bags are present, for that purpose we will use cv2.findContours.

def is_object_present(mask, threshold):
    im, contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    # Find the largest contour
    largest_contour = max(contours, key=lambda x:cv2.contourArea(x))
    if cv2.contourArea(largest_contour) > threshold:
        return True
    return False

Now you call this method on both the masks, to get individual values if red bean bag or blue bean bag is present:

# Adjust this manually as per your needs
bean_bag_area_threshold = 5000
is_red_bean_bag_present = is_object_present(mask_red, bean_bag_area_threshold)
is_blue_bean_bag_present = is_object_present(mask_blue, bean_bag_area_threshold)

if is_red_bean_bag_present and is_blue_bean_bag_present:
    print "Both bean bags are present." 

Upvotes: 2

Related Questions