Issue with Masking Red Color and Else Statement in OpenCV [closed]

I am encountering a problem with my OpenCV code where the else statement for masking red color isn’t working as expected. The code aims to apply different color masks based on the position of landmarks detected in an image. The other options for masking (blue and brown) are functioning correctly, but the red color mask seems to be ineffective.

Here is the relevant portion of the code:

# ... (previous code)

lower_red = np.array([0, 0, 0])
upper_red = np.array([180, 255, 255])

while True:
    # ... (previous code)

    if len(landmarks) != 0:
        if landmarks[8][1] < 350:
            mask = cv.inRange(hsv, lower_blue, upper_blue)
            img = cv.bitwise_and(img, img, mask=mask)
        else:
            mask = cv.inRange(hsv, lower_red, upper_red)
            img = cv.bitwise_and(img, img, mask=mask)
    else:
        mask = cv.inRange(hsv, lower_blue, upper_blue)
        img = cv.bitwise_and(img, img, mask=mask)

    # ... (previous code)

Despite efforts to troubleshoot and modify the code, the red color mask doesn’t seem to be applied correctly. I have tried adjusting the HSV range for red, but the issue persists.

If anyone has insights or suggestions on how to rectify this problem and ensure that the red color is correctly masked based on the positional condition, I would greatly appreciate the assistance.

and here is the full code

from detectors_world import DetectorCreator
import cv2 as cv
import numpy as np

cap = cv.VideoCapture(0)

creator = DetectorCreator()
hand = creator.getDetector("hand")
lower_blue = np.array([60, 35, 140]) 
upper_blue = np.array([180, 255, 255]) 
lower_red = np.array([0, 0, 0])
upper_red = np.array([180, 255, 255])
lower_brown = np.array([0, 0, 0])
upper_brown = np.array([180, 255, 255]) 
while True:
    status, img = cap.read()
    hand.detect(img, drawOnHand=True)
    landmarks = hand.locate(img)
    img=cv.resize (img,(700,500))
    img=cv.line(img,(350,0),(350,500),(255,0,0),5)
    hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)

    if len(landmarks) !=0:
        if landmarks[8][1]<350:
            mask = cv.inRange(hsv, lower_blue, upper_blue)
            img = cv.bitwise_and(img, img, mask=mask)

        
        else:
            mask = cv.inRange(hsv, lower_red, upper_red)
            img = cv.bitwise_and(img, img, mask=mask)
    else:
        mask = cv.inRange(hsv, lower_blue, upper_blue)
        img = cv.bitwise_and(img, img, mask=mask)

    cv.imshow("Hand Detection", img)
    k = cv.waitKey(1)
    if k % 255 == 27:
        break
cap.release()
cv.destroyAllWindows()

for clarification the program dosnt even try to mask the image

  • 1

    HSV red needs two ranges, one for 0+ (near and above 0) and one for 180- (near and below 180), since Hue is cyclical at 0 and 180 in OpenCV. If you want to threshold on red, you would be better using the Cr channel of YCbCr. See en.wikipedia.org/wiki/YCbCr

    – 

  • 1

    As an alternative to Fred’s suggestion above, you can invert your image before converting to HSV and then look for cyan, example here stackoverflow.com/a/59236916/2836621

    – 

  • Thanks Mark, I forgot about that. Good suggestion.

    – 

  • the issue isnt in the color its that the program dosnt even try to mask the color

    – 

Leave a Comment