From: Kenneth Galea on 5 Feb 2010 08:29 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 5 Feb 2010 08:40 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 5 Feb 2010 08:58 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 5 Feb 2010 09:05 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 5 Feb 2010 09:57
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 |