Generating a readable colour from RGB? - rgb

I'm putting in a function which will allow a user to input a color (eg: purple) and it will change the look of their profile to be purple. It's interpreted from text into a 'Color' class which stores them inside itself as RGB numbers (int for red, one for green and other for blue). What i don't know how to do is logically turn these three numbers into another 3 which will make a readable colour.
Can anyone help me on how to do this?
Joe

If I'm interpreting your question correctly, you're looking for a readable text color after someone has chosen a background theme color. This was answered in an older question:
Good text foreground color for a given background color

Obviously, there's not a name for every possible RGB combination! Presumably you want to find a nearby combination that you have specified a name for?
So really all you need is a way of defining how "close" one RGB is to another. For simplicity, I would suggest Euclidean-distance-squared, i.e. (R2-R1)^2 + (G2-G1)^2 + (B2-B1)^2. Then all you need to do is iterate through all your "named" colours, and find the one with the smallest distance.

You could look at the rgb.txt file that comes with X11.
A parser for that could provide a translation between those strings and the RGB values wouldn't be terribly hard to build and would likely do what you're looking for.

As others already say, there are 16.7 million possible combinations, all of which obviously can't have a defined name.
You're not going into detail about your use case, but if you want to make it end user friendly, how about using percentages?
80% red, 50% green, 23% blue
this is perfectly understandable for a non-technical person as well. You would limit (from 256^3 to 100^3) the number of possibilities if you use integer percentage values, but not as much as confining the user to a fixed palette of named colours.

Related

WPF dynamically scale TextBlock Text without filling a container

I have a set of pages that look like this:
I have the content in grids with * Heights and Widths so the grid correctly scales when the entire window resizes. I would like the text to resize with the grid. Basically I would like the user to resize from this:
To this:
(preserving white space)
One way to do this would be to wrap the TextBlock in a ViewBox with margins on the right and bottom (for Grid.Row="3") to account for white space. But because I have several pages with different lengths and line counts I would have to set the margin specifically for each page otherwise the text sizes would differ on each page. Is there a better way to do this??
I don't think there is a better way to do this. There are different ways. But, I think it isn't just a matter of opinion that they would not be better.
Ways I can think of.
Render your text offscreen, rendertargetbitmap that so you've got a picture. Change your textblocks on screen to images and stretch them.
Or
Work out the size your text wants to be. Then do some calculation comes up with a different fontsize which is "better". This is a lot easier to write a description of than do.
In my opinion.
A viewbox is easier to implement. Way less error prone than calculations. Will give at least as good results as rendering to a picture.
I just want to add one more solution to the ones suggested by Andy, which is more of a scientific approach and takes a bit of practice to master.
Suppose you have to find a function F, which maps one or more variables to a desired single value. In your case that would be a function F, which takes aspect ratio of the window as input and outputs an appropriate font size.
How can you find such a function?
Well... you don't need to do any math yourself!
First, you need some data to begin with:
1. Resize the window randomly
2. Calculate aspect ration (X)
3. Pick an appropriate font size that looks good enough (Y)
4. Repeat the measurement 7 to 10 times (sorry data scientists)
5. Enter the data in Excel - one column for X and another one for Y
6. Insert a scatter chart
7. Choose the best trendline for your data, but avoid the polynomial one
8. Display the trendline equation and use the expression in your code
Now I should mention the pros and cons of this regression technique.
Pros:
1. It can solve a wide range of tricky problems:
"I use this 3rd party control, but when the text is too long it overlaps the title bar. How to trim it so it doesn't go beyond the top border?. Deadline is coming!"
2. Even if it doesn't solve the problem perfectly, the results are often acceptable
3. It takes minutes to try out unlike spending a day refreshing your math skills
Cons:
1. The biggest problem is that to keep it simple, you often lower the number of
variables by assuming some of them to be constant. In this post I've assumed that
the font family won't change for example, neither the font weight.
2. If any of the assumptions does not hold the final result could be even worse
This technique is fragile, but powerful. Use it as your last weapon and never leave magic expression like
fontSize = (int)(0.76 + 1.2 * aspectRation) without documenting how it came to be.

How to go about changing the tint color of an image?

Sorry for the vague title, I have no idea how to really ask this question to be honest so I'll describe what I'm trying to do
I'm attempting to make an app where users can change the colors of different parts of a car. They can change the door for instance to a green as shown, or any other color they wish. They would then be able to change the color of the hood, or the roof, etc.
I've thought about having seperate images for each component and then lining them up to match. However this seems practically impossible when it comes to different screen sizes and scales. I also thought about making a blanket white image, and then creating views over the top with the selected color.
Does anyone have any ideas how I could possibly approach this?
Thankyou
I dont know about the performance of this. But, how about, an overlay of the different parts of the car, but using the same size of the whole car. For example, you have the image of the whole car, and erase all but the door. In other image, you erase all but the hood. If you lay one image above another, it will make the whole car, and the size of the screen will not affect you, because all the images will have the same size.
Then you can use the tint style to change the color of each layer.

How can I determine the colorspace (RGB) profile of my data?

I have a standard jpeg image, which I use within some commercial software to colorize other data (by mapping the image's color onto the data). Then I export the colored data from this software to an XYRGB ascii file, i.e. I store the data information in the first two columns of each row and then the three RGB colors in the last three columns.
Since I need to convert the color to CIELab or CIELuv, it seems I need to know which exact colorspace (RGB, sRGB, gamma, whitepoint - you name it) my RGB values are in. But the question is: How can I find out? Or could I just assume a certain profile being a good approximation?
(Remark: The company of the commercial software I used was not able to tell me any specifics...)
If you don't know the provenance of the image, there's not anything you can do to determine the color space from the RGB data alone. It's a little like having a blueprint without a scale. You could guess and check with an application like Photoshop that can assign a profile to an image but even then it's not always obvious which is correct unless the image contains colors you can recognize as correct.
For many images sRGB is good guess. Most image on the web are sRGB and many non-color managed apps assume sRGB. But just understand that it is still a guess. If color accuracy is critical, you need the profile.

Masking image data using values generate from a histogram in OpenCV

Given a generated histogram that I got from an image I was wondering if there was any optimized way to generate a mask. Below I have added in 3 different images: the reference to use, the histogram data of the reference, and the main image that I would like to mask. I know that I could do this by each pixel and vary the color information by a certain percentage so that I would be able to get colors with lighting changes as well.
The basic idea is to find a color, given by the histogram data and within a certain range, and if it finds anything then to make it black. If it doesn't find anything then the color will be white.
Any advice would be greatly appreciated.
Reference image:
Histogram values:
Image to mask:
What you want is to mask a color in a certain range, this is what you should try with the code i posted here :
In my example, it is used to make it transparent, if you want to make it black, just skip the cvNot() step...
Making a color completely transparent in OpenCV
Hope it helped,
Julien
PS : i've just seen that you were the one who asked the question I answered about how to make a color transparent: the problem here is exactly the same... just adapt a lil bit the answer..
1) Convert your image RGB -> HSV : cvtColor()
2) Generate your histogram : calcHist()
3) Find the maximum in your Hue histogram : minMaxLoc()
4) Select thresholds around this maximum : your function
5) Use them to select only the color you want : inRange()
6) Put this mask in black : your function (a very simple way would be to remove all the RGB components on the mask) : your function
Try to use template matching approaches instead of histogram, for example, normalized cross correlation http://www.mathworks.com/products/demos/image/cross_correlation/imreg.html.

Image processing..back ground subtraction

I have a sequence of images taken from a camera. The images consists of hand and surroundings. I need to remove everything except the hand.
I am new to Image processing. Would anyone help me in regard with the above Question. I am comfortable using C and Matlab.
A really simple approach if you have a stationary background and a moving hand (and quite a few images!) is simply to take the average of the set of images away from each image. If nothing else, it's a gentle introduction to Matlab.
The name of the problem you are trying to solve is "Image Segmentation". The Wikipedia page here: wiki is a good start.
If lighting consistency isn't a problem for you, I'd suggest starting with simple RGB thresholding and see how far that gets you before trying anything more complicated.
Have a look at OpenCV, a FOSS library for computer vision applications. Specifically, see the Video Surveillance module. For a walk through of background subtraction in MATLAB, see this EETimes article.
Can you specify what kind of images you have. Is the background moving or static? For a static background it is a bit straightforward. You simply need to subtract the incoming image from the background image. You can use some morphological operations to make it look better. They all depend on the quality of images that you have. If you have moving background I would suggest you go for color based segmentation. Convert the image to YCbCr then threshold appropriately. I know there are some papers available on it(However I dont have time to locate them). I suggest reading them first. Here is one link which might help you. Read the skin segmentation part.
http://www.stanford.edu/class/ee368/Project_03/Project/reports/ee368group08.pdf
background subtraction is simple to implement (estimate background as average of all frames, then subtract each frame from background and threshold resulting absolute difference) but unfortunately only works well if 1. camera has manual gain and exposure 2. lighting conditions do not change 3.background is stationary. 4. the background is visible for much longer than the foreground.
given your description i assume these are not the case - so what you can use - as already pointed out - is colour as a means of segmenting foreground from background. as it's a hand you are trying to isolate best bet is to learn the hand colour. opencv provides some means of doing this. if you want to do this yourself you just get the colour of some of the hand pixels (you would need to specify this manually for at least one frame) and convert them to HUE (which encapsulates the colour in a brightness independen way. skin colour has a very constant hue) and then make a HUE histogram. compare this to the rest of the pixels and then decided if the hue is simmilar enough.

Resources