Activate/deactivate pixel based on predominant color - python

I'm doing a real time image processing at about 20 FPS.
I'm trying to filter 3 colors (using opencv, python). Those are: red, blue and yellow from a frame in which the light is not always constant (meaning sometimes the ambiental light can make my red pixel (B=119, G=84, R=199), and sometimes (R=60, G=0, B=0) - this is when the light comes right in front of the camera).
I know about a formula like so : if 2R-B-G is grater or equal to 0, then the pixel will go high (it remains unchanged). If the pixel goes negative, i should make it black. The problem is that this involves a pixel by pixel processing and i'm not sure it is what i'm searching for. I would like to try this approach but i don't know how could i do it a little bit faster (masking and cv2.bitwise_and() after each pixel checked is the only ideea that I have, and it will take ages)
For the moment, i am just creating a binary_mask
cv2.inRange(bgr_sliced_img, (low_blue, low_green, low_red), (upper_blue, upper_green, upper_red))
The problem with this is that it is impossible to adjust the parameters so that i get the red /blue/ yellow values visible in darker images as well as in bright images without seeing other wrong objects.
I've read this and i don't really know how could i use the median intensity in my frame. I think this is close to what i want, but i have no ideea how could i implement this.
I will provide 3 pictures that ilustrates the problem . The traffic stop sign is red, but because of ambiental light, its red is changed.
I would like to find some algorithm that will "see" the red color in each 3 pictures without the need of manual modifying parameters.
*I should mention that i'm searching for the traffic sign in a region of interest of about 100x100 pixels, not in the entire image

Related

Eye pupil corner detection (openCV)

I am trying to make a program in openCV (python) that can tell when an eye pupil is straight or at corners (left or right). What I have done so far is:
Took an image, cropped the eye part (detected the region through eye_cascade.detectMultiScale(gray)) (picture is attached).
Got BGR value ofpixel of img[(3*h)/4,w/2] (h=height, w=width)
Tried to mask the skin by converting BRG to HSV, did thresh_BINARY to get only remaining white shade of around pupil.
count white pixels and checked if either side has less than 40% of white pixels then decide the position of pupil.
This method gives somewhat good answer for picture but when I start the webcam, masking fails thus failing further entire process.
Anyone has better idea on how I can do this? (Already read all the answered questions on this forum but couldn't find a satisfactory solution).
Image
I think it is because binary thresholding outputs pixels greater than Scalar 127 as white and the remaining as black. This gives really bad results in dark ( where most pixels are less than 127 ) and light ( where most pixels have more than 127 value).
What you can do is to find the mean and standard deviation.
Then you can define a mask in such a way that all pixels above
mean+k*std_deviation
as white pixels. You can find the constant k by experimenting with various images.
Good Luck!

How to remove black -grid programmatically?

My ideas are:
1.0. [unsolved, hard image-detection] Breaking image into squares and removing borders, surely other techniques!
1.1. [unsolved] Imagemagick: crop (instructions here), remove
certain borders -- this may take a
lot of time to locate the grid, image detection
problem (comparing white/black here) -- or there may be some magic wand style filter.
1.2. [unsolved] Python: you probably need thisfrom PIL import Image.
Obivously, Gimp's eraser is the wrong way to solve this problem since it's slow and error-prone. How would you remove the grid programmatically?
P.s. Casual discussion about this problem in Graphics.SE here that contains more physical and mechanical hacks.
If all images consist of black lines over a gray grid, you could adjust the white threshold to remove the grid (e.g. with ImageMagick):
convert -white-threshold 80% with-grid.png without-grid.png
You will probably have to experiment with the exact threshold value. 80% worked for me with your sample image. This will make the lines pixelated. But perhaps resampling can reduce that to an acceptable amount, e.g. with:
convert -resize 200% -white-threshold 80% -resize 50% with-grid.png without-grid.png
In your image the grid is somewhat lighter than the drawing, so we can set a threshold, and filter the image such that all 'light' pixels are set to white. Using PIL it could look like this:
import Image
def filter(x):
#200 is our cutoff, try adjusting it to see the difference.
if x > 200:
return 255
return x
im = Image.open('bird.png')
im = im.point(filter)
im.show()
Processing your uploaded image with this code gives:
Which in this case is a pretty good result. Provided your drawing is darker than the grid, you should be able to use this method without too many problems.
Feedback to the answers: emulbreh and fraxel
The python -version utilizes the ImageMagick so let's consider the ImageMagick. It does not work with colored version like the below due to different color-channel -profiles. Let's investigate this a bit further.
$ convert -white-threshold 0% bird.png without.png
This picture shows the amount of noise in the original scanned picture.
Puzzle: removing the right -hand corner as an example
I inversed the colors $ convert -negate whiteVersion.png blackVersion.png to make it easier to vizualise. Now with the below black photo, I wanted to remove the blue right corner i.e. make it black -- it means that I want to set BG channels to 0 of BG with 100% channel -value.
$ convert -channel BG -threshold 100% bbird.png without.png
Now the only thing left is of course Red -channel, I removed GB but white still have Red left. Now how can I remove just the right-hand -corner? I need to specify area and then do the earlier -operations.
How can I get this working with arbitrary photo where you want to remove certain color but leave some colors intact?
I don't know an easy way. The first problem is color-detection problem -- you specify some condition for colors (R,G,B) with some inequality. If the condition is true, you remove it in just the part. Now you do this for all basic colors i.e. when (R,G,B)=(100%,0,0), (R,G,B)=(0,100%,0) and (R,G,B)=(0,0,100%). Does there exist some ready implementation for this? Probably but it is much nicer to do it yourself, puzzle set!
Prerequisite knowledge
Tutorials here and here about Imagemagick.
In order to understand this topic, we need to know some basic physics: white color is a mixture of all colors and black consists of no colors.

Capture motion in Python

I want to capture the motion of a red paper on a white background in Linux using Python? I will be using OpenCV and an image library to create images at 30fps. Is there a way I can detetmine the position of the red paper (or a point on it) without going through every pixel in the image, since that would make it horribly slow. Or is there a better way of doing this altogether?
The code for reading the webcam is posted here.
Here is the full code, but for yellow paper. Change color range in line 18 for red color.
And it works only if single yellow paper is present.
And here is another code for the same, but now it works even if more than one yellow paper is present. Again change it to red yourself.

How to identify stripes of different colors

how can I identify the presence or absence of regular stripes of different colors, but ranging from very very very very light pink to black inside of a scanned image (bitmap 200x200dpi 24-bit).
Carry a few examples.
Example 1
Example 2 (the lines are in all the columns except 7 in the second row of the last column)
For now try to identify (using python language) whether or not there is at least 5-10 pixels for the presence of different color from white to each strip, however, does not always work because the scanned image is not of high quality and the strip changes color very similar to color that surrounds it.
Thanks.
This looks to me a connected component labeling in an image to identify discrete regions of certain color range. You can have a look to cvBlobLib. Some pre-processing would be required to merge the pixels if there are holes or small variations between neighbors.
Not going to happen. The human visual system is far better than any image processing system, and I don't see anything in the 2nd row of #3. #1 and #5 are also debatable.
You need to find some way to increase the optical quality of your input.
Search for segmentation algorithm ,with a low threshold.
It should give you good results as the edges are sharp.
Sobel would be a good start ;)

Finding images with pure colours

I've read a number of questions on finding the colour palette of an image, but my problem is slightly different. I'm looking for images made up of pure colours: pictures of the open sky, colourful photo backgrounds, red brick walls etc.
So far I've used the App Engine Image.histogram() function to produce a histogram, filter out values below a certain occurrence threshold, and average the remaining ones down. That still seems to leave in a lot of extraneous photographs where there are blobs of pure colour in a mixed bag of other photos.
Any ideas much appreciated!
How about doing this?
Blur the image using some fast blurring algorithm. (Search for stack blur or box blur)
Compute standard deviation of the pixels in RGB domain, once for each color.
Discard the image if the standard deviation is beyond a certain threshold.
In my opinion a histogram will not be the ideal tool for the this task since it typically looks at separately at each color channel and you will loose information like this. So for example if you get peaks at 255 red, green and blue this can either mean that there is lots of red (0xFF0000), green (0x00FF00) and blue ( 0x0000FF) in the image or that the whole image is simply entirely white ( 0xFFFFFF).
I recommend you to use a color quantization algorithm on your image: http://en.wikipedia.org/wiki/Color_quantization and have it return you the 16 most dominant colors. Then maybe convert them to HSL and check for values with a high saturation.

Categories

Resources