Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the RED color regions using OpenCV?

I am trying to make a program where I detect red. However sometimes it is darker than usual so I can't just use one value. What is a good range for detecting different shades of red? I am currently using the range 128, 0, 0 - 255, 60, 60 but sometimes it doesn't even detect a red object I put in front of it.

like image 464
huvarda Avatar asked Dec 03 '22 11:12

huvarda


2 Answers

RGBis not a good color space for specific color detection. HSV will be a good choice.

For RED, you can choose the HSV range (0,50,20) ~ (5,255,255) and (175,50,20)~(180,255,255)using the following colormap. Of course, the RED range is not that precise, but it is just ok.

enter image description here

The code taken from my another answer: Detect whether a pixel is red or not

#!/usr/bin/python3
# 2018.07.08 10:39:15 CST
# 2018.07.08 11:09:44 CST
import cv2
import numpy as np
## Read and merge
img = cv2.imread("ColorChecker.png")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

## Gen lower mask (0-5) and upper mask (175-180) of RED
mask1 = cv2.inRange(img_hsv, (0,50,20), (5,255,255))
mask2 = cv2.inRange(img_hsv, (175,50,20), (180,255,255))

## Merge the mask and crop the red regions
mask = cv2.bitwise_or(mask1, mask2 )
croped = cv2.bitwise_and(img, img, mask=mask)

## Display
cv2.imshow("mask", mask)
cv2.imshow("croped", croped)
cv2.waitKey()

enter image description here

Related answers:

  1. Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)
  2. How to define a threshold value to detect only green colour objects in an image :Opencv
  3. How to detect two different colors using `cv2.inRange` in Python-OpenCV?
  4. Detect whether a pixel is red or not

Of course, for the specific question, maybe other color space is also OK.

How to read utility meter needle with opencv?

like image 50
Kinght 金 Avatar answered Dec 23 '22 15:12

Kinght 金


You could check that the red component is the maximum and others are both clearly lower:

def red(r, g, b):
    threshold = max(r, g, b)
    return (
        threshold > 8          # stay away from black
        and r == threshold     # red is biggest component
        and g < threshold*0.5  # green is much smaller
        and b < threshold*0.5  # so is b
    )

This can be implemented very efficiently using numpy.

The "right way" would be doing a full conversion to HSV and check there, but it's going to be slower and somewhat trickier (hue is an angle so you cannot just take the absolute value of the difference, moreover colors like (255, 254, 254) are going to be qualified as "red" even if they're considered white for a human).

Note also that human visual system tends to compensate for average, so something could be seen as "blue" even if indeed the biggest component is red, but everything in the image is red, so that "doesn't count" for our brain.

In the image below if you ask a human what color is the part in the circle area most would say "blue" while indeed the biggest component is red:

A reddish lenna

like image 21
6502 Avatar answered Dec 23 '22 13:12

6502