I need to get the RGB of a HSL with the SL both max. (get RGB from 125, 100, 100)
So, just the hue is changing.
Is there a simple formula for this?
Thanks
See Converting to RGB towards the end of http://en.wikipedia.org/wiki/HSL_and_HSV
In HSL color mode, if L = 100, then S = 0 and H = undefined.
Yes theres a formula. RGB = (255, 255, 255). When L is 100 (max), then your R,G,B is maxed (ie white), no matter what the Hue, or even Saturation.
Related
I am trying to create a custom palette of transparent colours with gnuplot:
a=127
rgb(i,a)=int(255*256**(i%3)+(i/3)*96*256**((i+1)%3)+a*256**3)
then I do obtain the desired colours:
plot x w l lc rgb rgb(0,a) lw 32, x+1 w l lc rgb rgb(1,a) lw 32
Problem, if a is equal or greater than 128, int returns a negative number which is then not recognized as a colour. Is there a way to get an unsigned int in gnuplot? Or any other way to get numbers understood as hex beyond #80000000 ?
Use the operator left shift unsigned <<, check help operators binary.
Also check this: https://stackoverflow.com/a/60257784/7295599
Code:
### create your own transparent palette
reset session
# a,r,g,b should be integers between 0 and 255 (or 0x00 and 0xff)
a = 127 # transparency
r = 0xff # red
g = 0x00 # green
b = 0x00 # blue
myColor(a,r,g,b) = (a<<24) + (r<<16) + (g<<8) + b
# put some objects in the background to demonstrate transparency
set object 1 rect from -7,0 to -3,250 fs solid 1.0 fc rgb "green" behind
set object 2 rect from 3,0 to 7,250 fs solid 1.0 fc rgb "blue" behind
plot for [a=0:250:10] a w l lw 5 lc rgb myColor(a,r,g,b) notitle
### end of code
Result:
First, consider this code:
from PIL import Image
im = Image.open("best_tt.jpg")
im2 = Image.new("RGB", im.size, (255,255,255))
b = 200
for i in range(im.size[0]):
for j in range(im.size[1]):
rgb = im.getpixel((i,j))
if rgb[0] <= b and rgb[1] <= b and rgb[2] <= b:
im2.putpixel((i,j), (0,0,0))
else:
im2.putpixel((i,j), (0, rgb[1], rgb[2]))
im2.save("tmp.jpg")
What I am doing is simply removing the RED component from each pixel (other than black pixels: the if statement checks for pixels that look black). In other words, I'm converting the given image to a yellow scale (since G+B = Y).
In that way, every pixel should have an RGB value like (0, G, B).
However, certain pixels of the new image returned values like:
(1, 255, 203)
(3, 205, 243)
(16, 242, 47)
though some had the red component as 0.
What causes this arbitrary adjustment of the RGB values?
The save() function will determine the type as a jpeg, which has a default compression quality of 75. The way the file is encoded and compressed can end up changing values after the fact.
See the PIL documentation for save() below:
https://pillow.readthedocs.io/en/3.1.x/handbook/image-file-formats.html
The problem I have at hand is to draw boundaries around a white ball. But the ball is present in different illuminations. Using canny edge detections and Hough transform for circles, I am able to detect the ball in bright light/partial bright light but not in low illumination.
So can anyone help with this problem.
The code that I have tried is below.
img=cv2.imread('14_04_2018_10_38_51_.8242_P_B_142_17197493.png.png')
cimg=img.copy()
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.medianBlur(img,5)
edges=cv2.Canny(edges,200,200)
circles = cv2.HoughCircles(edges,cv2.HOUGH_GRADIENT,1,20,
param1=25,param2=10,minRadius=0,maxRadius=0)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(255,255,255),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.imwrite('segmented_out.png',cimg)
else:
print("no circles")
cv2.imwrite('edges_out.png',edges)
In the image below we need to segment if the ball is in the shadow region as well.
The output should be something like below images..
Well I am not very experienced in OpenCV or Python but I am learning as well. Probably not very pythonic piece of code but you could try this:
import cv2
import math
circ=0
n = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220]
img = cv2.imread("ball1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
for i in n:
ret, threshold = cv2.threshold(gray,i,255,cv2.THRESH_BINARY)
im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
for j in range(0, len(contours)):
size = cv2.contourArea(contours[j])
if 500 < size < 5000:
if circ > 0:
(x,y),radius = cv2.minEnclosingCircle(contours[j])
radius = int(radius)
area = cv2.contourArea(contours[j])
circif = 4*area/(math.pi*(radius*2)**2)
if circif > circ:
circ = float(circif)
radiusx = radius
center = (int(x),int(y))
elif circ == 0:
(x,y),radius = cv2.minEnclosingCircle(contours[j])
radius = int(radius)
area = cv2.contourArea(contours[j])
circ = 4*area/(math.pi*(radius*2)**2)
else:
pass
cv2.circle(img,center,radiusx,(0,255,0),2)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.detroyAllWindows()
What it does is acctually you convert your picture to grayscale and apply different threshold settings to it. Then you eliminate noises with adding size to your specific contour. When you find it, you check its circularity (NOTE: it is not a scientific formula) and compare it to the next circularity. Perfect circle should return the result 1, so the highest number that will get in a contour (of all the contours) will be your ball.
Result:
NOTE: I haven't tried increasing the limit of size so maybe higher limit could return better result if you have a high resolution picture
Working with grayscale image will make you subject to different light conditions.
To be free from this I suggest to work in HSV color space, then use the Hue component instead of the grayscale image.
Hue is independent from the light condition, since it gives you information about the color, regardless of its Saturation or Value (a value bound to the brightness of the image).
This might bring you some clarity about color spaces and which is best to use for image segmentation.
In your case here. We have a white ball.White is not a color by itself.The main factor here is, what kind light actually falls on the white ballAs the kind of light that falls on it has a direct influence on the kind of extraction you might plan to do using a color space like HSV as mentioned above by #magicleon
HSV is your best bet for segmentation here.Using
whiteObject = cv2.inRange(hsvImage,lowerHSVLimit,upperHSVLimit)
lowerHSVLimit and upperHSVLimit HSV color range
Keeping in mind that the conditions
1) The image have similar conditions while they were clicked
2) You cover all the ranges of HSV before extraction
Hope you get an idea
Consider this example
Selecting a particular hue range from 45 to 60
Code
image = cv2.imread('allcolors.png')
hsvImg = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
lowerHSVLimit = np.array([45,0,0])
upperHSVLimit = np.array([60,255,255])
colour = cv2.inRange(hsvImg,lowerHSVLimit,upperHSVLimit)
plt.subplot(111), plt.imshow(colour,cmap="gray")
plt.title('hue range from 45 to 60'), plt.xticks([]), plt.yticks([])
plt.show()
Here the hue selected from 45 to 60
I'm using Cairo to draw figures. I found that Cairo uses a "absolute coordinate" when drawing. It is a flexible and comfortable way, except specify the line_width. Because of the ratio of the below image is not 1:1, when the "absolute coordinate" converted to "real coordinate", the width of the lines are not same.
WIDTH = 960
HEIGHT = 640
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
ctx.scale(WIDTH, HEIGHT)
ctx.rectangle(0, 0, 1, 1)
ctx.set_source_rgb(255, 255, 255)
ctx.fill()
ctx.set_source_rgb(0, 0, 0)
ctx.move_to(0.5, 0)
ctx.line_to(0.5, 1)
ctx.move_to(0, 0.5)
ctx.line_to(1, 0.5)
ctx.set_line_width(0.01)
ctx.stroke()
What is the correct way to make line_width shown as the same ratio in the output image?
Undo your call to ctx.scale() before calling stroke(), for example via:
ctx.save()
ctx.set_line_width(2)
ctx.identity_matrix()
ctx.restore()
(The save()/restore() pair applies all your transformations again afterwards)
I'm trying to convert some HSL value to RBG with Data.Colour module. Hackage doc said that Hue is always in the range 0-360. But there are now any ranges of Saturation and Lightness values. Are they in [0,100] or in [0,1] ranges?
I suppose that first variant is right, but seems like it is not.
λ> hsl 100 50 50
RGB {channelRed = 866.6666666666692, channelGreen = -2400.0, channelBlue = 2500.0}
Than I tried to use the range [0, 1] for both saturation and lightness.
λ> fmap truncate . (\(h,s,l) -> hsl h s l) $ (0,0,0)
RGB {channelRed = 0, channelGreen = 0, channelBlue = 0}
it :: RGB Integer
That why I'm start thinking that only Saturation should be a Double in [0,1].
For example we have some color value in HSL format.
λ> let c = (34.0,0.54,68.0)
c :: (Double, Double, Double)
Than we convert it to RGB and truncate all values
λ> fmap truncate . (\(h,s,l) -> hsl h s l) $ c
RGB {channelRed = 31, channelGreen = 63, channelBlue = 104}
But (31,63,104)::RGB is (214,54,26)::HSL like some online color-converters said.
What am I doing wrong?
It looks like the package uses the range [0, 1] for both lightness and saturation, but note that it also uses this range for RGB values, and not [0, 255] as you seem to be assuming. Taking this into account, I get (almost) the expected values:
> fmap (truncate . (* 255)) $ hsl 214 0.54 0.26
RGB {channelRed = 30, channelGreen = 61, channelBlue = 102}
So finally I've figured out that both Saturation and Lightness value should be in the [0,1] range.
λ> fmap (round . (255*)). (\(h,s,l) -> hsl h s l) $ (34.0,0.54,0.68)
RGB {channelRed = 217, channelGreen = 179, channelBlue = 129}
it :: RGB Integer
It makes a sense, because (217,179,129)::RGB value is equal to (34,54,68)::HSL.
So, maybe it would be helpful to add that constrains in the docs.