Method to extract specific color range from an image not working in Python

asked 2018-09-13 12:15:48 -0500

bwrr gravatar image

I'm trying to extract a specific color from an image within a defined BGR range using the cv2 module using Python 3. In the example below I am trying to isolate the fire from the exhaust of the space shuttle between yellow and white BGR values and then print out the percentage of RGB values within that range compared to the rest of the image.

Here is my minimal working example:

import cv2
import numpy as np
from matplotlib import pyplot as plt
import imageio

img = imageio.imread(r"shuttle.jpg")
cv2.imshow('original',img)
cv2.waitKey(1)

This is the output image. Its from wikipedia.

image description

#CONVERT TO HSV COLORS
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
color1 = np.uint8([[[0, 255, 255 ]]]) #yellow in BGR
color2 = np.uint8([[[255, 255, 255]]]) #white in BGR
hsv_color1 = cv2.cvtColor(color1,cv2.COLOR_BGR2HSV)
hsv_color2 = cv2.cvtColor(color2,cv2.COLOR_BGR2HSV)

print(hsv_color1)
print(hsv_color2)

#Define threshold color range to filter
mask = cv2.inRange(hsv_img, hsv_color1, hsv_color2)

# Bitwise-AND mask and original image
res = cv2.bitwise_and(hsv_img, hsv_img, mask=mask)
ratio = cv2.countNonZero(mask)/(hsv_img.size/3)
print('pixel percentage:', np.round(ratio*100, 2))
#plt.imshow(mask)

cv2.imshow('mask',res)
cv2.waitKey(1)

However this does not seem to work because I get 0% of pixels between the yellow and white values. I'm not really sure where I'm going wrong:

Output

[[[ 30 255 255]]]
[[[  0   0 255]]]
pixel percentage: 0.0

And the output "res or mask" graph appears to be blank with a black image:

image description

Also when I just try to output the original image, it appears in a strange inverted color format:

cv2.imshow('hsv_img',hsv_img)

image description

Anyway, I have tried following the OpenCV tutorial on this but can't seem to get it to work: https://docs.opencv.org/3.2.0/df/d9d/...

I guess what I'm tried to achieve here is something like the image below where only the colors between yellow and white are displayed, and then print out the percentage of pixels consisting of these colors. For the image below I just filtered out all colors below RGB (255, 255, 0) for yellow using a basic image processing software.

Is there a way to achieve this using the code I have already written or similar?

image description

edit retag flag offensive close merge delete

Comments

your img is in hsv colorspace, while your ranges are for bgr (you need to change those)

berak gravatar imageberak ( 2018-09-13 12:25:49 -0500 )edit
1

also, Hue is in the [0..180] range here.

berak gravatar imageberak ( 2018-09-13 12:26:42 -0500 )edit
1

Doesn't COLOR_BGR2HSV convert the BGR color1 and color2 ranges to HSV space? Thats what I did in the code.

bwrr gravatar imagebwrr ( 2018-09-13 12:34:34 -0500 )edit