Finding objects in images with inhomogeneous background
A better way of removing the background might be to use a TotalVariationFilter
, which seems to be less sensitive to the parameter it is given compared to convolution. In fact, I've not even used any parameters.
Your code can also be simplified since Binarize
takes a Method
option. In fact, you don't actually need it, the automatic method works just as well.
The size option of DeleteSmallComponents[]
depends on the minimum feature size in your image, so using a value of 1 is a good assumption in this example, but may vary for other images.
image = Import["http://i.stack.imgur.com/czhuI.png"];
background = TotalVariationFilter[image];
subImage = ImageSubtract[image, background];
(* Or use Binarize[subImage, Method -> "Entropy"]; *)
binImg = DeleteSmallComponents[Binarize@subImage, 1];
resultImage = Show[image,
Graphics[{Red, Disk[#, 2] & /@
ComponentMeasurements[binImg, "Centroid"][[All, 2]]}]
]
BilateralFilter replaces each pixel by a weighted average of its neighbors, using normalized Gaussian matrices as weights.
so
BilateralFilter[i, 4, 1]
is "almost" your background.
If you have troubles with fine-tuning for other images, you may "calculate" the 4
as
Round[Sqrt[Total@Flatten@ImageData@SelectComponents[MaxDetect[i], "Area", -1]/Pi] // N]
(* 4 *)
Use it like this:
pts = ComponentMeasurements[Binarize@ImageSubtract[i, BilateralFilter[i, 4, 1]],
"Centroid"];
Show[i, Graphics[{Red, Point[pts[[All, 2]]]}]]