How to find various colours from image without giving range of colour - python

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)

Related

Is there a way I can extract markers on a map image using python?

I have an image here, sample map
I wish to extract red lines on the map. The lines represent the number of times a user has chosen a path. The darker the color, the more times he chose that path.
Also, if I know the zoom level of the map (in this case 11), can I calculate the distance traveled for every color marker?
Thanks,
Try this code -
import numpy as np
import cv2
image = cv2.imread('test.jpg')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([155,25,0])
upper = np.array([179,255,255])
mask = cv2.inRange(image, lower, upper)
result = cv2.bitwise_and(result, result, mask=mask)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.imwrite('output.jpg', result)
cv2.waitKey()
Output -

How to convert a range of gray pixels to black with opencv?

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)

Analyze an image in specific area and determine if it's red using Opencv Python

I'm using Opencv python in raspberry pi, to analize a heatmap, i'm looking for color red, which represents the highest temperature, i need to detect if in an specific area exist red color, in case it does i can use this information to activate a condition, i'm using a heatmap like this:
for the red color detection i'm using this code:
import cv2
import numpy as np
while(1):
# Take each frame
frame = cv2.imread('heatmap.png')
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_red = np.array([-20, 100, 100])
upper_red = np.array([13, 255, 255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_red, upper_red)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('heatmap',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
the code above give me al the pixels in red, but i need to determine if the heatmap contour is red, i mean the image contour or border would be a red color not permited area, does anyone how i can do that?
Your HSV range is not right. For red, (0,20,20)~(8,255,255), (170,20,20) ~ (180,255,255).
Here is my result:
The code:
#!/usr/bin/python3
# 2018/05/16 13:54:09
import cv2
import numpy as np
img = cv2.imread('heatmap.png')
# Convert BGR to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask1 = cv2.inRange(hsv, (0,20,20), (8,255,255))
mask2 = cv2.inRange(hsv, (170,20,20), (180,255,255))
mask = cv2.bitwise_or(mask1, mask2)
dst = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow("dst", dst)
cv2.imwrite("__.png", dst)
cv2.waitKey()
Some useful links:
Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)
How to define a threshold value to detect only green colour objects in an image :Opencv

Detecting Colors on object in OpenCV - Python

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.

How does filtering out the colors of a hsv image in opencv python work?

I am working on a project that needs to identify the shape of an object in a field. My goal right now is to filter out any colors the background could be such as green, brown, or gray.
import cv2
import numpy as np
img = cv2.imread('pic1.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_green = np.array([0,0, 150])
upper_green = np.array([255, 255, 255])
mask = cv2.inRange(hsv, lower_green, upper_green)
res = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow('res1.png', res)
cv2.waitKey(0)
The image
is showing a sample of the shapes in the field.
This code results in this image:
Why do the values I use for the lower and upper greens remove all the green when I have only included red values?
Are there any ways to get filters that remove only one color so I am able to pick and choose which colors I would want to keep and which to remove?

Categories

Resources