I am having an issue with color detection in OpenCV 3.4. I will present a picture of my problem below.
import numpy as np
import cv2
img= cv2.imread("C:\\Users\Stefan_Cepa\\Desktop\\dataset2\\set\\A6.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_range = np.array([30,150,150])
upper_range = np.array([255,255,180])
mask = cv2.inRange(hsv, lower_range, upper_range)
output = cv2.bitwise_and(img, img, mask = mask)
cv2.imshow("images", np.hstack([img, output]))
cv2.imshow('mask', mask)
while(True):
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
As you can see I've set my lower and upper bounds to detect Red color in an image, but for some reason, as you can see in image below, I am not getting any results. Any tips & tricks would be extremely helpful! Thank you in advance!
You are using the hsv colorspace but you are providing ranges of bgr values. they are incompatible.
For hsv:
For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255]. Different softwares use different scales. So if you are comparing OpenCV values with them, you need to normalize these ranges.
source: docs.opencv.org/3.2.0
Your code almost looks like this: http://pyimagesearch.com/2014/08/04/opencv-python-color-detection. Only they use bgr.
Solution:
Convert your mask-ranges to hsv or load images as bgr.
Red on hsv is on hue 0 so you probably would need a combined mask of 170-180 hue and 0-10 hue.
Related
I am working with OpenCV and Tesseract. I was trying to convert a range of grey pixels to black. Example:
As you can see there is a "bright" multiple grey color, I need to convert that to full black for OCR to be able to read it better.
Does anyone know how to do so?
import cv2
import numpy as np I = cv2.imread('imgPath')
## If you are interested in thresholding based on brightness,
## using grey channel or brightness channel from HSV is always a good idea :)
# Convert input RGB to HSV
HSV = cv2.cvtColor(I, cv2.COLOR_BGR2HSV)
# Get brightness channel
V = HSV[:, :, 2]
# Threshold all the very bright pixels
bw = 255*np.uint8(V < 200)
# save the image you want
cv2.imwrite("bw.png", bw)
Need to read the images and do the color changes illustrated below for each of the masks, as shown below.
I thought of first converting the black into white using: imageWithMask = cv2.bitwise_not(image)
I'm thinking they're two ways to do this
One split the image into two and change the colors
Other is to use a threshold and convert which I don't know properly, looking for any assistance with the same.
## Read
img = cv2.imread("your_image_path.jpg")
## convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
## mask of lower red (0,50,50) ~ (10,255,255)
mask1 = cv2.inRange(hsv, (0,50,50), (10,255,255))
## mask of upper red (170,50,50) ~ (180,255,255)
mask2 = cv2.inRange(hsv, (170,50,50), (180,255,255))
## final mask and masked
mask = cv2.bitwise_or(mask1, mask2)
## target = cv2.bitwise_and(img,img, mask=mask)
inverseGrayImage = numpy.uint8(255) - mask;
plt.imshow(inverseGrayImage,cmap='gray')
cv2.imwrite("result.jpg", inverseGrayImage)
I need to separate yellow colour from this image. I tried with opencv cv2.inrange and thresholding but it didn't give satisfactory results. Whenever lighting conditions change shade of colour will change so please suggest any other algorithm.
Here is where HSV value system plays a role. The normal rgb value filtering can give different results in different lighting conditions. But, HSV can help you to select only the specific color less susceptible to ligthing conditions .
image=cv2.imread('image.jpg')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower_yellow = np.array([20,100,100])
upper_yellow = np.array([30,255,255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_blue, upper_blue)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(image,image, mask= mask)
cv2.imshow('res',res)
#press any key to quit
cv2.waitKey(0)
cv2.destroyAllWindows()
You can learn more about hsv and its applications here,
https://www.kirupa.com/design/little_about_color_hsv_rgb.htm
https://docs.opencv.org/3.4.2/df/d9d/tutorial_py_colorspaces.html
http://aishack.in/tutorials/tracking-colored-objects-opencv/
# I tried with code
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
threshold=0.667
#load image
img=plt.imread(r'C:\Users\Desktop\pbr\artik image\pbr2.jpg')
#extract each color channel
red, green, blue=img[:,:,0],img[:,:,1],img[:,:,2]
#total red+green+biue intensity
intensity=img.sum(axis=2)
add2=np.sum(intensity)
#function to calculate proportion of a certain channel
def color_frac(color):
return np.sum(color)/np.sum(intensity)
#calculate proportion of each color
red_fraction=color_frac(red)
green_fraction=color_frac(green)
blue_fraction=color_frac(blue)
sum_color_fraction=red_fraction+green_fraction+blue_fraction
print('Red fraction:{}'.format(red_fraction))
print('\nGreen fraction:{}'.format(green_fraction))
print('\nBlue fraction:{}'.format(blue_fraction))
print('\nRGB sum:{}'.format(sum_color_fraction))
print(red.shape==green.shape==blue.shape)
add1=red_fraction+green_fraction
green1=green.astype(float)
red1=red.astype(float)
yellow=green1+red1
check=yellow/intensity
j=check
df=pd.DataFrame.from_records(check)
Bad=df[df>threshold].count().sum()
df[df>threshold]=1
df[df<=threshold]=0
df=df.fillna(1)
data=df*255
data=df.astype(np.uint8)
plt.imshow(data)
#plt.imshow(green)
#plr.imshow(red+green)
I am using Raspberry Pi 3 and Pi camera. I am doing an image processing program that could detect yellow colour and right now I am testing it but in frame nothing happen.My color detection is wrong?
Here is my code:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of yellow color in HSV
lower_yellow = np.array([204,204,0])
upper_yellow = np.array([255,255,254])
# Threshold the HSV image to get only yellow colors
mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
The problem is that you're filtering an HSV image with what looks to be RGB values. If you're looking for yellow, then you want to have a narrow hue range, and then saturation and value wider.
Yellow is roughly 60 degrees for hue, which means around a value of 30 for OpenCV (as the hue value is half the degree value to it can fit in the range 0-255). Similarly, your saturation and value shouldn't be the full range of 0-255 otherwise things that are close to black or white will match.
Try something like
lower_yellow = np.array([20, 30, 30])
upper_yellow = np.array([40, 200, 300])
This will hopefully get you close, but you still may have to play around with the numbers to get what you want.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_green, upper_green)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
Note: i'm new to open cv ,so please help guys!!!
In this program
while reading a frame , why is there the symbol ' _, ' before frame
is it a syntax??
The lowerbound and upper bound of blue color is specified.
is that RGB values or BGR values or HSV values??
How can i find lower bound and upperbound of others colors like red,green?
Please explain the process of finding values of other colour ,i tried other colours but it gave me black screen output for hsv and res!!!
Can some one change this program to detect red color or other color so i can know the difference?
This is tuple unpacking; cap.read() returns two values, we assign the first to _ (convention for "we won't be using this") and the second to frame.
The comment literally says "in hsv".
You just need to specify your own bounds, or change the ones already there, and see the difference yourself. Use an HSV converter to see what colours you are using. If the colours within your range aren't in the image you process, it will be black.