Eamorr
Eamorr

Reputation: 10012

Python: detect black squares

Example image

I'm trying to detect the black square.

Here is my code sofar...

    frame=cv2.imread('squares.jpg')
    img=cv2.GaussianBlur(frame, (5,5), 0)

    img=cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    lower=np.array([0, 0, 0],np.uint8)
    upper=np.array([10, 50, 50],np.uint8)
    separated=cv2.inRange(img,lower,upper)


    #this bit draws a red rectangle around the detected region
    contours,hierarchy=cv2.findContours(separated,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    max_area = 0
    largest_contour = None
    for idx, contour in enumerate(contours):
        area = cv2.contourArea(contour)
        if area > max_area:
            max_area = area
            largest_contour=contour
            if not largest_contour==None:
                moment = cv2.moments(largest_contour)
                if moment["m00"] > 1000:
                    rect = cv2.minAreaRect(largest_contour)
                    rect = ((rect[0][0], rect[0][1]), (rect[1][0], rect[1][1]), rect[2])
                    (width,height)=(rect[1][0],rect[1][1])
                    print str(width)+" "+str(height)
                    box = cv2.cv.BoxPoints(rect)
                    box = np.int0(box)
                    if(height>0.9*width and height<1.1*width):
                            cv2.drawContours(frame,[box], 0, (0, 0, 255), 2)

    cv2.imshow('img',frame)

I'm then trying to draw a red square around the detected black region.

The code works for yellow, orange, red and green with the following parameters:

colours=['yellow','orange','red','green','black','white']
uppers=[[20,100,100],[5,100,100],[0,100,100],[???,???,???],[???,???,???]]
lowers=[[30,255,255],[15,255,255],[6,255,255],[???,???,???],[???,???,???]]

I just can't get black or white to work...

Any thoughts?

Upvotes: 3

Views: 9283

Answers (1)

Aurelius
Aurelius

Reputation: 11329

The key intuition here is that black is located at all hue and saturation values in the HSV cylinder, but only at low value values. I found that a lower bound [0, 0, 0] and an upper bound [180, 255, 50] will locate the black square, like so:

Located black box

I should also mention that your method will not work for finding the white squares, for several reasons:

  • There exist multiple white squares. Your method only selects the largest contour which means only one square can ever be detected per color.
  • It would be difficult to distinguish the "white squares" from the color of the paper they are printed on. You will likely get a single contour connecting the square and the strip of paper on the sides.

Upvotes: 4

Related Questions