Find out how much of a rectangle is filled with a color using OpenCV

Question:

I am using a webcam to segment a green piece of paper. I have tried different results using inRange and thresholding but have gotten a pretty good result so far.
I now have a rectangle in the middle of the screen which I want to check how much of it is filled with that green color because the camera will be moving, the rectangle will also be moving. And if 80% of the rectangle is filled with green color I want to return True.

Here’s my code so far

import numpy as np
import cv2

cap = cv2.VideoCapture(1)
while True:

    succ,img = cap.read()
    lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    lab = cv2.GaussianBlur(lab,(5,5),0)
    a_channel = lab[:,:,1]
    #th = cv2.threshold(a_channel,127,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]
    th = cv2.threshold(a_channel, 115, 255, cv2.THRESH_BINARY_INV)[1]
    masked = cv2.bitwise_and(img, img, mask = th)

    cv2.rectangle(masked,(640,440),(1280,548),(0,255,0),3)
    cv2.imshow('mask',masked)

    cv2.waitKey(1)

The picture returned is below, you can see the rectangle and the green piece of paper.
I would like to move the piece of paper closer to the rectangle and have it return True if its almost filled with the green color

output

Asked By: SchoolOfTheYear

||

Answers:

To check if the rectangle is filled with the green color, you can use the following steps:

  1. Create a binary mask using the inRange method, with the range of the green color in the LAB color space. This will create a binary image where the green pixels are white, and the rest are black.

  2. Use the bitwise_and method to apply this binary mask on the original image, to get only the green pixels in the rectangle.

  3. Use the countNonZero method to count the number of white pixels in the rectangle.

  4. Calculate the percentage of white pixels in the rectangle by dividing the number of white pixels by the total number of pixels in the rectangle.

  5. If the percentage is greater than or equal to 80%, return True. Otherwise, return False.

Here is an implementation of these steps:

import numpy as np
import cv2

cap = cv2.VideoCapture(1)
while True:

    # Capture the frame from the webcam
    succ, img = cap.read()
    if not succ:
        break

    # Convert the image to LAB color space
    lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)

    # Apply Gaussian blur to remove noise
    lab = cv2.GaussianBlur(lab, (5,5), 0)

    # Extract the A channel from the LAB image
    a_channel = lab[:,:,1]

    # Create a binary mask using the inRange method, with the range of the green color in the LAB color space
    green_mask = cv2.inRange(lab, (50, 0, 0), (100, 255, 255))

    # Use the bitwise_and method to apply this binary mask on the original image, to get only the green pixels in the rectangle
    masked = cv2.bitwise_and(img, img, mask=green_mask)

    # Draw the rectangle on the masked image
    cv2.rectangle(masked, (640, 440), (1280, 548), (0,255,0), 3)

    # Count the number of white pixels in the rectangle
    white_pixels = cv2.countNonZero(green_mask[440:548, 640:1280])

    # Calculate the percentage of white pixels in the rectangle
    green_percentage = white_pixels / (1280 - 640) * (548 - 440)

    # Check if the percentage is greater than or equal to 80%
    if green_percentage >= 0.8:
        print("The rectangle is filled with green color!")

    # Display the masked image
    cv2.imshow('mask', masked)

    # Wait for 1ms
    cv2.waitKey(1)

# Release the webcam
cap.release()
Answered By: skalthoff
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.