1

We can define the range of red color in HSV as below. I want to detect that whether a certain pixel is red or not? How can I do that in Python? I spend whole day, but unable to find solution. Please resolve my problem. I'm very new to Python. Code that I'm using is:

img=cv2.imread("img.png")
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

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

# upper mask (170-180)
lower_red = np.array([170,50,50])
upper_red = np.array([180,255,255])
mask1 = cv2.inRange(img_hsv, lower_red, upper_red)
image_height,image_width,_=img.shape    
for i in range(image_height):
   for j in range(image_width):
       if img_hsv[i][j][1]>=lower_red and img_hsv[i][j][1]<=upper_red:
          print("Found red")
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Knowledge Seeker
  • 526
  • 7
  • 25
  • 1
    Can you post the error that you are getting? – Jose Vasquez Jul 07 '18 at 17:57
  • @JoseVasquez img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV) cv2.error: OpenCV(3.4.1) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:11214: error: (-215) (scn == 3 || scn == 4) && (depth == 0 || depth == 5) in function cv::cvtColor – Knowledge Seeker Jul 07 '18 at 17:59
  • @JoseVasquez This is the error that I'm getting. – Knowledge Seeker Jul 07 '18 at 18:00
  • 1
    @KnowledgeSeeker Use `img=cv2.imread("img.png", 1) in the first line ` – Jeru Luke Jul 07 '18 at 18:03
  • @JeruLuke I used, but still getting same error. I used all resources to find solution, but unable to reach solution. :( – Knowledge Seeker Jul 07 '18 at 18:06
  • Make sure the image has 3 or 4 channels. To get the image dimensions , do `print(img.shape)`. The result will be in the form of (height,width,channels). – zindarod Jul 07 '18 at 18:51
  • make sure that the image isnt empty. imshow it or test it. Maybe a problem with working directory path or sth. – Micka Jul 07 '18 at 19:33
  • 2
    after you fixed the error, this line will be a problem: if img_hsv[i][j][1]>=lower_red and img_hsv[i][j][1]<=upper_red: Change it so you test if(mask0 or mask1 at the pixel is set) – Micka Jul 07 '18 at 19:35
  • @Micka can you suggest proper code solution to achieve this ? – Knowledge Seeker Jul 07 '18 at 21:13
  • Why are you looping over every pixel when you say you only want to detect if a certain pixel is red? Which is it? One certain pixel or all of them? The aporoach is different depending on the answer. The former is a single pixel test, the latter would be vectorised numpy or OpenCV function. – Mark Setchell Jul 07 '18 at 21:57
  • @KnowledgeSeeker unfortunately, my numpy/python skills aren't good enough to post the code.But probably it is: `if mask0[i][j]>0 or mask1[i][j]>0:` – Micka Jul 07 '18 at 22:45

1 Answers1

6

You are almost right. You can merge the masks of lower RED and higher RED together to a single mask.


For this ColorChecker.png:

enter image description here

My Steps to find the RED:

  1. Read the image and convert to hsv.

  2. I choose the red ranges (lower 0~5, upper 175~180) using this colormap:

enter image description here

  1. Then merge the masks, you can judge whether the pixel is red or not by the mask. Or "crop" the region(s) for visualization:

enter image description here


#!/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()

  1. Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)

  2. How to detect two different colors using `cv2.inRange` in Python-OpenCV?

Community
  • 1
  • 1
Kinght 金
  • 17,681
  • 4
  • 60
  • 74