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
>Solution :
To check if the rectangle is filled with the green color, you can use the following steps:
-
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.
-
Use the bitwise_and method to apply this binary mask on the original image, to get only the green pixels in the rectangle.
-
Use the countNonZero method to count the number of white pixels in the rectangle.
-
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.
-
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()
