Treating Against the Light Photos to Detect Red Marker from the Sky

Hi! I’m currently working on a project right now that is able to detect red markers from the sky.
My color masks are working great.

However, when I tried testing the algorithm by taking pictures of red markers from the sky, I ran across the problem of having against the Light Photos.
My red markers go dark and the pixels don’t become red anymore. See the photo.

Only one pixel is detected that is red. Shown in the picture, only one pixel is color white.

So, I’m curious if there are opencv-python treatments to preprocess this image first, or capturing images issue, or it can’t be solved at all? Thanks!

Here’s my code:

path = r'C:\Users\ #location of the image
image = cv2.imread(path, 1)
img = image

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

# lower mask (0-10)
lower_red = np.array([0,100,100]) # 0,50,50 original
upper_red = np.array([10,255,255]) 
mask0 = cv2.inRange(img_hsv, lower_red, upper_red) 

# upper mask (170-180)
lower_red = np.array([160,100,100]) # 170,50,50 original
upper_red = np.array([180,255,255])
mask1 = cv2.inRange(img_hsv, lower_red, upper_red)

mask = mask0+mask1

output_img = img.copy()
output_img[np.where(mask==0)] = 0
output_img[np.where(mask!=0)] = 255

what are you doing , so far, to detect the markers ? please show code.
(maybe it can be improved by using hsv colorspace ? who knows …)

you could control your camera’s exposure. the marker will look better when the sky is overexposed.

and yes, we need to see code. there’s no reason that picture shouldn’t work. marker is red and saturated and not too dark to make those values noisy. I tried that just now and it works just fine.

Hi. I edited the post with the code. Thanks a lot :smiley:

Oh. Can you teach me how? I edited my post together with the code.

play with the lower bound’s Value value. the marker is darker than 100.

generally, play with parameters.

also: you should not use np.where in your code at all.

  • it’s not needed. simply use a mask as “the index”: output_img[mask==0] = 0
  • np.where is doing one of two things depending on number of arguments. if you must, use np.nonzero

I’ve seen people abuse np.where a lot recently. did someone make a new youtube tutorial?

actually, np.where is the code I used to convert the image to binary, 255 for the detected red and 0 for the undetected. I’ve been doing OpenCV and I’m still not an expert.
So based on what you recommend, np.nonzero could probably lessen my runtime error.

if you use np.where(mask_array, consequence_values, alternative_values) (three arguments), and you need the effect it produces, then it’s the best tool for the task.

if you’re just overwriting parts of an array using a mask, you can just do

im[mask_array] = consequence_values[mask_array]
# and/or
im[~mask_array] = alternative_values[~mask_array]

in case the values arrays are arrays. if not, the indexing on the right hand side doesn’t happen at all.

1 Like