From: Kenneth Galea on
ImageAnalyst <imageanalyst(a)mailinator.com> wrote in message <c8eeb205-2cbb-4f95-a108-feeb4c668a14(a)l26g2000yqd.googlegroups.com>...
> Well then you might have to do more complicated things than
> thresholding, such as color classification. See my simple demo here:
> http://www.mathworks.com/matlabcentral/fileexchange/26420-simplecolordetection
> Actually this color detection demo is so simple that it just uses
> thresholding, but on all three color planes and then combines them.
> So it's basically chopping out a rectangular gamut out of the 3D RGB
> color space. There are more sophisticated color classification method
> that can be done if necessary. But you can do this type of thing to
> detect your background color and then everything not background will
> be foreground (your objects).
>
> If you are able to choose your background color then you might be able
> to get your object mask just by looking at a particular color plane,
> or by subtracting or dividing your test image by a reference (blank)
> background image that has nothing in it except the background (no
> objects present).
>
> There are even more methods but we can't get into all possbilities of
> methods. It would be best if you posted some images (such as to
> http:://drop.io which is the easiest) that illustrate the thresholding
> difficulties you are having.
Hi thanks for your reply
This link shows my problems http://drop.io/objectthreshold
With objects thresholding is perfect. Without objects (but exactly the same background) thresholding is sick :/ as you can see. Complications are what I really need to eliminate unfortunately :/
Thanks
From: ImageAnalyst on
Well the shadows are going to cause you a problem because it won't
know if you want to consider shadows an object or not. They're simply
a different color than the background, just like everything else in
the photo.

But your problem is that you're thresholding before background
correction. You want to threshold AFTER you get the background
corrected image.

First of all, convert the images to floating point. Then either
subtract or divide your test image by your background image. It's at
THIS point that you threshold. Actually you'll have two thresholds,
for subtraction, everything less than some negative tolerance or
greater than a positive tolerance will be foreground (bitand()those
two thresholded images together), or
for division, everything less than (1.0 - some tolerance) or greater
than (1 + some tolerance) will be foreground (bitand() those two
thresholded images together).

Then call label, and call regionprops. You might want to do a little
clean up either before of after thresholding, such as small object
removal (use bwareaopen) or hole filling (imfill), or boundary
smoothing (imclose), etc.
From: Kenneth Galea on
ImageAnalyst <imageanalyst(a)mailinator.com> wrote in message <02124bab-d7f0-4848-ba04-7f17b82d0ea0(a)f11g2000yqm.googlegroups.com>...
> Well the shadows are going to cause you a problem because it won't
> know if you want to consider shadows an object or not. They're simply
> a different color than the background, just like everything else in
> the photo.
>
> But your problem is that you're thresholding before background
> correction. You want to threshold AFTER you get the background
> corrected image.
>
> First of all, convert the images to floating point. Then either
> subtract or divide your test image by your background image. It's at
> THIS point that you threshold. Actually you'll have two thresholds,
> for subtraction, everything less than some negative tolerance or
> greater than a positive tolerance will be foreground (bitand()those
> two thresholded images together), or
> for division, everything less than (1.0 - some tolerance) or greater
> than (1 + some tolerance) will be foreground (bitand() those two
> thresholded images together).
>
> Then call label, and call regionprops. You might want to do a little
> clean up either before of after thresholding, such as small object
> removal (use bwareaopen) or hole filling (imfill), or boundary
> smoothing (imclose), etc.

That sounds great. However I'm not up to standard to certain things you said such as what I have to do before thresholding :) Labelling, regionprops, small object removal hole filling and boundary smoothing are all done. Can you please show me a simple code (few lines) of how to achive floating point conversion, subtraction/division and dealing of the two thresholds before finally thresholding automatically.
Thanks again
Kenneth
From: ImageAnalyst on
Look at the color detection demo - it has right in there some code to
threshold a range. You'd do something like

tolerance = 2; % Gray levels.
binaryImageRed = (subtractedImageRed < tolerance) &
(subtractedImageRed > tolerance);
same for green and red, then and them together
binaryImage = binaryImage Red & binaryImageGreen & binaryImageBlue;

labeledImage = bwconncomp(binaryImage);
measurements = regionprops(labeledImage);

Or, for divided images,
tolerance = 0.2; % Gray levels.
binaryImageRed = (dividedImageRed < (1.0 - tolerance)) &
(dividedImageRed > (1+tolerance));
etc.

You'll have to subtract or divide every color channel one at a time.
redPlane = double(rgbImage(:, :, 1));
greenPlane = double(rgbImage(:, :, 2));
bluePlane = double(rgbImage(:, :, 3));
do this for both your test image, and your background image, so that
you have two red images, two green images, and two blue images. Then
subtract or divide them.
From: Kenneth Galea on
ImageAnalyst <imageanalyst(a)mailinator.com> wrote in message <4e2e9862-9014-476e-95b7-db349024b01e(a)h2g2000yqj.googlegroups.com>...
> Look at the color detection demo - it has right in there some code to
> threshold a range. You'd do something like
>
> tolerance = 2; % Gray levels.
> binaryImageRed = (subtractedImageRed < tolerance) &
> (subtractedImageRed > tolerance);
> same for green and red, then and them together
> binaryImage = binaryImage Red & binaryImageGreen & binaryImageBlue;
>
> labeledImage = bwconncomp(binaryImage);
> measurements = regionprops(labeledImage);
>
> Or, for divided images,
> tolerance = 0.2; % Gray levels.
> binaryImageRed = (dividedImageRed < (1.0 - tolerance)) &
> (dividedImageRed > (1+tolerance));
> etc.
>
> You'll have to subtract or divide every color channel one at a time.
> redPlane = double(rgbImage(:, :, 1));
> greenPlane = double(rgbImage(:, :, 2));
> bluePlane = double(rgbImage(:, :, 3));
> do this for both your test image, and your background image, so that
> you have two red images, two green images, and two blue images. Then
> subtract or divide them.

I understood the concept. You are great. I tried it out but I'm having a minor problem. Maybe a small error in my code. This is my code:
background = imread('C:\Users\Kenneth\Desktop\test3.jpg');
test = imread('C:\Users\Kenneth\Desktop\test3.jpg');
redPlane_test = double(test(:, :, 1));
greenPlane_test = double(test(:, :, 2));
bluePlane_test = double(test(:, :, 3));

redPlane_background = double(background(:, :, 1));
greenPlane_background = double(background(:, :, 2));
bluePlane_background = double(background(:, :, 3));

binaryImageRed = redPlane_test - redPlane_background;
binaryImageGreen = greenPlane_test - greenPlane_background;
binaryImageBlue = bluePlane_test - bluePlane_background;
binaryImage = binaryImageRed & binaryImageGreen & binaryImageBlue

imshow(binaryImage)

In this case since my test image is background (to check if it becomes white) it's becoming totally black:/ It's surely a small bug in my code grrr!! Pls help

Thanks
Kenneth