whats the ranges of the red in HSV? - image-processing

i want to detect red objects in an image.so i convert RGB img to HSV. so in order to know the range of red color i used color pallet on this site
https://alloyui.com/examples/color-picker/hsv
I found out that H(Hue) is falling between 0 to 10 as a lower limit and 340 to 359 as an upper limit. also i found out that the maximum value of S(Saturation) and V(value) is 100. but the problem is that i found some people say the ranges of red H: 0 to 10 as lower limit and 160 to 180 as uper limit.
https://solarianprogrammer.com/2015/05/08/detect-red-circles-image-using-opencv/
OpenCV better detection of red color?
also they said the maximum S and V is 255.This is color i got when i tried to find the upper limit of the red

There are different definitions of HSV, so the values your particular conversion function gives are the ones your should use. Measuring them is the best way to know for sure.
In principle H is an angle, so it goes from 0 to 360, with red centered around 0 (and understanding that 360==0). But some implementations will divide that by 2 to fit it in 8 bits. Others scale to a full 0-255 rage for the 8 bits.
The same is true for S and V. Sometimes they're values between 0 and 100, sometimes they go up to 255.
To measure, create an image where you have pure red pixels (RGB value 255,0,0), and convert. That will give your the center of red hue (H) and the max saturation (S). Then make an image that changes from orange to purple, these colors are near red. You should then see the range of H. Finally, make a pure white image (255,255,255). This will have maximum intensity (V).

Related

Interpretation of color histogram

I'm reading a paper about image processing and came across this color histogram:
image. But I'm not sure how to interpet it. The 3 different curves are for red, green and blue. But what is on the X and Y-axis? My guess would be X-axis going from 0 to 255 for the 'intensity' of the color and Y-axis the amount of pixels in the image that have this intensity. Could anyone confirm this or correct me if I'm wrong?
If I know well, someone please correct me if I am wrong, the X axis represents the possible values of a color from either one of the RGB channels (a value in the [0-255] interval), and the Y axis represents the number of pixels having that value.

RGB value of a pixel, combined from 2 overlaying pixels

I am creating an animated gif with Water and Land. The Land part has shores, so the water will in some cases be overlaying those shores. However, I wish the shores to still be slightly visible underneath the water. Basically, imagine 1 transparent png which represents water, over another that has sand. The 2 images combined can be viewed as a third image.
My question is - how would I calculate the RGB value of the new pixels, based on the top ones RGBA (with transparency) and the bottom ones RGB values, to mimic a natural look.
I will change the transparency level myself to see what suits me best, but I'm missing a formula.
EDIT:
atm I do have 1 idea - take the percentage of the transparency level of the water, and based on that percentage calculate a new RGB. Do the same for the sand pixels, but with the "remaining" percentage (100-transparency%)
ie (A part is in %, for simplicity)
(R1,G1,B1, 40) (R2,G2,B2) = 40% of first group + 60% of second
Alpha blending is either dead simple (alpha is on 0-255, so the colour is destination * (255 - a) + overlay * a, all over 255) or quite subtle, when you allow the destination to also have alpha. Also it is necessary to implement efficiently for many applications, which is done by pre-multiplying, then hardcoding the division by 255 using
((x+1) * 257) >> 16;
Malcolm McLean gives the correct answer for the case where destination (aka background) is completely opaque, which happens to be the case we are discussing.
Just for completeness, I'd like you give the formula for the general case and the intuition behind it.
First of all, assume our colors are 4-component floating-point vectors, with each channel having values between 0 and 1. Also assume our colors are alpha-premultiplied, that is the r, g and b channels are pre-multiplied by the alpha channel. Then the alpha-blending formula is:
blended = front + back * (1.0 - front.a)
The intuition is: we are taking the front color and adding to it a bit of the back color, namely as much as we can see through the front color.
Note that the blended color is also alpha-premultiplied.

binarization of colours in images

I am extracting primitives from pixel-based line diagrams and wish select by colour. Thus in the following
I wish to extract the "blue", the "green" and the "black" primitives. (I am prepared to try to reconstruct primitives which have been split by primitives of another colour).
However the "blues" have a varying amount of white added (similar to a gray scale for black). Thus the commonest colours (rounded to 12-bit for simplicity) with their counts might be
000 881 // black
88f 1089 // white-blue
fff 70475 // white
but there are other degrees of whiteness at lower frequency
// other white-blue
99f 207
// other grey
ddd 196
I believe that the authors will have used only a very limited number of pure colours (e.g. 3-6) in many diagrams and that various rendering tools will have added the white. IOW the colours can be expressed by (0 =< x =< 1)
000 + x(FFF)
00F + x(FF0) // blue
0F0 + x(F0F) // green
However there is no requirement to use primary colours and the set could be any colour with arbitrary amounts of white.
How can I reconstruct the (small) set of different colours? If this is possible I can then select those regions, transform to grey, and binarize in the normal way.
I'd prefer source in Java but I suspect that any code will be adequate;
I have read two useful SO questions
"Rounding" colour values to the nearest of a small set of colours
HCL color to RGB and backward
which use H-C-L and might be a way forward although they don't directly answer my requirements.
You could try using region growing. I think it should fit your needs well. Just change the threshold for when it's the same color. I think it should work well here since there seems to be a big difference between any two colors that are connected as objects.
If your intuition is correct (all pixels being a linear mixture of some color and pure white), in the RGB cube all colors will be aligned on line segments originating from the white corner.
If you pick one representative pixel per different color (as far as possible from white, for better accuracy), you can identify the color of any other pixel by finding the best alignment formed by this pixel, by white and by the representative pixels.
Alignment is tested by computing the cosine of the angle formed (use 3D vectors, the cosine is the dot product over the product of the norms; drop the sign). In theory the cosine should be exactly 1, but due to numerical errors it can be smaller, so just consider the representative color that maximizes the cosine.
Take special care of the white pixels (short distance to the white corner), otherwise they will be randomly assigned to some representative color.
Depending on the number of colors involved and their similarity, a simple threshold of the R, G, and B values would quickly reduce everything to one of 8 colors (black, red, green, blue, cyan, magenta, yellow, or white).

Getting dominance color opencv

I have a image which is multi colored.
I want to calculate the dominant color of the image. the dominant color is red, i want to filter the red out. i am doing the following code in opencv but its not performing.
inRange(input_image, Scalar(0, 0, 0), Scalar(0, 0, 255), output);
How can i get the dominant color otherwise? My final project should determine the maximum color of the object on its own. What is the best method for this?
You should quantize (reduce number of colors) your image before searching the for the most frequent color.
Why? Imagine image that has 100 pixels of (0,0,255) (blue color int RGB), 100 pixels of (0,0,254) (almost blue - you even won't find the difference) and 150 pixels of (0,255,0) (green). What is the most frequent color here? Obviously, it's green. But after quantization you will got 200 pixels of blue and 150 pixels of green.
Read this discussion: How to reduce the number of colors in an image with OpenCV?. Here's simple example:
int coef = 200;
Mat quantized = img/coef;
quantized = quantized*coef;
And this is what I've got after applying it:
Also you can use k-means or mean-shift to do that (this is much efficient way).
The best method is by analyzing histograms.
Your problem is a classical "find the peak and area under the peak". By having an image file (let's say we take only the third channel for simplicity):
You will have to find the highest peak in that histogram. The easiest method is to simply query the X for which Y is maximized. More advanced methods work with windows - they average the Y-values of 10 consecutive data points, etc.
Also, work in the HSV or YCrCb color space. HSV is good because the "Hue" channel translates very closely to what you mean by "Color". RGB is really not well suited for image analysis.

Poisson blending rgb out of range

I am trying to blend two images using Poisson Blending technique. I have written the program and solved the system of linear equations separately for each r,g,b channel. After solving the equation rgb values are going out of bound, each value greater than 255. If I clamp each value to 255, the resulting image becomes white as all three channes are 255 now. My question is that can the rgb values be greater than 255 after solving poisson equation ? How can I have a proper blended image in this case ?
I think you need to change your scale for color values. According to the formula given in most of the online sites (set of equations), they consider the color value to be in the 0 to 1 range. Convert your 0 - 255 scale to floating point values between 0 - 1 and see.

Resources