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
CodePudding user response:
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()