How can I binarize images with text? [MATLAB] - image

I have a problem with a binarization method.
I have images with text, which I want to binarize.
I want the text ends up being white, but there are images with the text darker than the background and there are images with text less dark than the background.
I want to binarize images like these, but I want the text in white color in the binarized images.
By the way, I am binarizing images with this code. This code is good for images with text darker than the background but it isn't good for text less darker than the background. I think I need a method to know if the text is more or less dark than the background for to invert or no invert the binarization.
umb = graythresh(originalImage);
binaryImage =(~im2bw(originalImage,umb));
How can I do it?
Thanks a lot for the help

there are 2 possible solutions which I had in mind:
solution1:
generate a grayscale image using rgb2gray function.
generate a histogram from the grayscale image, and ignore the transparent pixels. you can use imhist function.
check what is the histogram maximal value. if the value is high - the background is probably light and the text should be darker than the background. in this case - take the negative image (for example, by using imcomplement), and then binarize it. otherwise - you can binarize it as is.
solution 2:
the solution asserts that the image is simple enough, i.e. doesn't have a lot of connected components other than the letters.
binarize the input image.
divide the image into connected components using bwconncomp function.
for each connected component find it's representative value, it can either be 0 or 1
check what is the most common represantative value. if it is 1 - the letters are dark. in this case take the negative image and than binarize. otherwise - binarize the input image as is.
good luck!

Related

Binarized grayscale image contains too much noise

I currently have a digital pathology image like this:
Firstly I turn the image into grayscale using the following codes:
img=imread('DigitalPathology8.png');
figure;
imshow(img)
hsv=rgb2hsv(img);
s=hsv(:,:,2);
And I got this grayscale image:
While I try to binarize this grayscale image using the following codes:
bw = imbinarize(s,'global');
figure
subplot(2,1,1)
imshow(s)
subplot(2,1,2)
imshow(bw)
I got the image like this:
What's wrong with my codes? When I applied the same algorithm to other images like this:
I could get the binarized image which only blue cells are white and other cells including backgrounds are black. So I also expect the same result after I applying the same codes to the first image I mentioned.
Could someone please help me out?
You should better use the rgb2gray()(look here) for your conversion:
grey=rgb2gray(img)
This should get you something like this:
Instead of global thresholding, i would recommend more sophisticated methods such as Otsu, which will get you much better results:
However, if you only want to extract the blue cells instead of a simple thresholded version of your image, you should use a totally different approach like MaxEntropy on the grayscale image. This will give you something like this:
and this
This tresholding method does not seem to be included in matlab, but a plugin can be found.
You could also try a total different approach to detect the blue dots by thresholding based on color similarity:
With this approach you would set each pixel to white which has a color distance to the blue color which is smaller than a given threshold. This should give you something like this (red markings represent the foreground of the image):
Reference color:
For this approach i took the RGB color (17.3,32.5,54.5) as reference color, my max distance was 210. If you have ImageJ, you can this approach interactivly, a while back i wrote a plugin for that.As you can see, this approach also detects wrong cells, which is caused by the high value for the distance and the choosen reference color. This errors may be minimized by selecting a more appropriate reference color and smaller distance values.

There have any process to detect an image is a black&white image or a colored image?

I need to detect an image is a color image or black&white image. But don't understand what will be the process or there have any function to detect it. If there have no function to detect it then what will be the process?
Image file has mode, which tells if it is RGB, grayscale or B&W.
I assume you know that and you are trying to examine a RGB image to see if it only has black / white color. In this case you can calculate the histogram of the image in all R/G/B channels, the black and white will have two sharp peaks in all three channels.
Please use a image editing software like GIMP and experiment.

UIImage - highlight single color only

I need to convert an image to greyscale except for a single color. For example, if there is some red in the image (like a red bus), this will remain in color, but the rest of the image will remain in black & white.
I think I should be able to do a rudimentary job of this by going over each pixel individually, such as here: http://brandontreb.com/image-manipulation-retrieving-and-updating-pixel-values-for-a-uiimage . I am assuming I would just leave certain pixels alone if their red component was above a certain amount, and green/blue was below a certain amount. Otherwise, set the pixel to grayscale. Is this a good approach?
I'm more interested in whether or not it is possible to do to the live camera input, such as with a Core Image filter, or using GPUImage, but I haven't been able to find any suitable filters. Any suggestions?
Update:
This seems to be possible using GPUImage with a GPUImageLookupFilter, as per: https://stackoverflow.com/a/19340583/334982
I've created a lookup.png file in Photoshop, by dropping the Saturation for all colours except red to 0. This works ok, but it doesn't seem to grey out all colours. For example, my skin still looks fairly skin coloured, and my brown table is still fairly brown.

Best natural way of coloring an icon/sprite

I wanna to color a sprite/icon with a transparent background and with shadows. I tried to shift the hue to all pixels but it looks not so natural and I have problems with the black and the white colors in an image. If an image tend to be black shifting the hue do not change the black in red or another color even shifting by 360 degrees.
Tried to color addicting and subtracting color and even in that case the black and the white tend to be colored or disappears at all.
Maybe should I put an image on the icon to achieve the coloring effect ?
Any suggestions on how to proceed.
I lost.
You've been asking a lot about this hue shifting thing, so I figured I'd try to work out an example: http://jsfiddle.net/EMujN/3/
Here's another that uses an actual icon: http://jsfiddle.net/EMujN/4/
There's a lot in there. There's a huge data URL which you can ignore unless you want to replace it. Here's the relevant part where we modify HSL.
//SHIFT H HERE
var hMod = .3;
hsl[0]=(hsl[0]+hMod)%1;
//MODIFY S HERE
var sMod = .6;
hsl[1]=Math.max(0,Math.min(1,
hsl[1]+sMod
));
//MODIFY L HERE
var lMod = 0;
hsl[2]=Math.max(0,Math.min(1,
hsl[2]+lMod
));
I've converted to HSL because it's a lot easier to accomplish what you want in that color space than RGB.
Without getting any more complex, you have three variables you can tune: how much to add to either Hue, Saturation, or Lightness. I have the lightness variable set to 0 because any higher and you will see some nasty JPEG artifacts (if you can find a decent .png that would be better, but I went with the first CC night image I could find).
I think the hue shift (yellow to green) looks pretty good though and I have maxed out the saturation, so even a normally white light appears bright purple. Like I said in my comment, you will need to increase the lightness and saturation if you want to colorize patches of black and white. Hopefully, you can figure out what you need from this example.
image used: http://commons.wikimedia.org/wiki/File:Amman_(Jordan)_at_night.jpg
I found a better solution by myself which can solve the problem with the black and white.
So basically the solution can be solved in multiple steps. Here I will define the steps. Later I'll provide some working code:
Get the image
Calculate the predominant color, averaging the image pixels or simply providing an input RGB value which is the predominant that your eye can catch.
If the predominant tends to be black or white, or both, the image has to be recolored with an addictive or subtractive method, addictive if black, subtractive if white. So basically all RGB pixels should be attenuated or sharpened until RED. I think that the best solution should be RED, because RED is first in the HUE scale, and this can help when we will hue-shift the pixels.
To have a unique algorithm which can work with different kind of images, not only black predominant or white, ideally the input the non-black and non-white predominant images should be pre-hueshifted manually, using photoshop or with another algorithm in a way that the new predominant color results to be RED too
After that the Hue shifting coloring is straighforward. We know that the predominant color is RED for all the images, and we'll shift the HUE values with a difference between the HSV value of the desired color and the HSV of the predominant color (RED).
Game over. We have a pretty universal way to color different images with hue shifting in a natural way.
Another question could be how to authomatically pre-shift the input images which predominant color is not black or white.
But this is another question.
Why this coloring method could be considered natural. Simply consider one thing. Generally the non dominant black or white colors are part of the shadows and light which gives a 3D feel to the images. On the other hand if my shoes are 100% black and i will tint them with some colors, they will no more be black. Color the dominant black cannot be achieved simply shifting the HSV parameters but other steps should be performed. The steps are the above described.

Edge Detection and transparency

Using images of articles of clothing taken against a consistent background, I would like to make all pixels in the image transparent except for the clothing. What is the best way to go about this? I have researched the algorithms that are common for this and the open source library opencv. Aside from rolling my own or using opencv is there an easy way to do this? I am open to any language or platform.
Thanks
If your background is consistend in an image but inconsistent across images it could get tricky, but here is what I would do:
Separate the image into some intensity/colour form such as YUV or Lab.
Make a histogram over the colour part. Find the most occuring colour, this is (most likely) your background (update) maybe a better trick here would be to find the most occuring colour of all pixels within one or two pixels from the edge of the image.
Starting from the eddges of the image, set all pixels that have that colour and are connected to the edge through pixels of that colour to transparent.
The edge of the piece of clothing is now going to look a bit ugly because it consist of pixels that gain their colour from both the background and the piece of clothing. To combat this you need to do a bit more work:
Find the edge of the piece of clothing through some edge detection mechanism.
Replace the colour of the edge pixels with a blend of the colour just "inside" the edge pixel (i.e. the colour of the clothing in that region) and transparent (if your output image format supports that).
If you want to get really fancy, you increase the transparency depending on how much "like" the background colour the colour of that pixel is.
Basically, find the color of the background and subtract it, but I guess you knew this. It's a little tricky to do this all automatically, but it seems possible.
First, take a look at blob detection with OpenCV and see if this is basically done for you.
To do it yourself:
find the background: There are several options. Probably easiest is to histogram the image, and the large number of pixels with similar values are the background, and if there are two large collections, the background will be the one with a big hole in the middle. Another approach is to take a band around the perimeter as the background color, but this seems inferior as, for example, reflection from a flash could dramatically brighten more centrally located background pixels.
remove the background: a first take at this would be to threshold the image based on the background color, and then run the "open" or "close" algorithms on this, and then use this as a mask to select your clothing article. (The point of open/close is to not remove small background colored items on the clothing, like black buttons on a white blouse, or, say, bright reflections on black clothing.)
OpenCV is a good tool for this.
The trickiest part of this will probably be at the shadow around the object (e.g. a black jacket on a white background will have a continuous gray shadow at some of the edges and where to make this cut?), but if you get this far, post another question.
if you know the exact color intensity of the background and it will never change and the articles of clothing will never coincide with this color, then this is a simple application of background subtraction, that is everything that is not a particular color intensity is considered an "on" pixel, one of interest. You can then use connected component labeling (http://en.wikipedia.org/wiki/Connected_Component_Labeling) to figure out seperate groupings of objects.
for a color image, with the same background on every pictures:
convert your image to HSV or HSL
determine the Hue value of the background (+/-10): do this step once, using photoshop for example, then use the same value on all your pictures.
perform a color threshold: on the hue channel exclude the hue of the background ([0,hue[ + ]hue, 255] typically), for all other channels include the whole value range (0 to 255 typically). this will select pixels which are NOT the background.
perform a "fill holes" operation (normally found along blob analysis or labelling functions) to complete the part of the clothes which may have been of the same color than the background.
now you have an image which is a "mask" of the clothes: non-zero pixels represents the clothes, 0 pixels represents the background.
this step of the processing depends on how you want to make pixels transparent: typically, if you save your image as PNG with an alpha (transparency) channel, use a logical AND (also called "masking") operation between the alpha channel of the original image and the mask build in the previous step.
voilĂ , the background disappeared, save the resulting image.

Resources