5
$\begingroup$

Consider the following image:

enter image description here

Imagine I have several images (let's say 40), that look like this one but with slightly different cloud shapes, pixel count intensities and distances between the clouds.

Do you have a sure fire algorithm that would be able to localize all seven clouds with preferably no human input except for the 40 images. In the end the goal is to get the total pixel count in each cloud for the 40 images. I am aware that it is difficult to define what a cloud is exactly given the smooth nature of the shapes and the noisy nature of the image. Any definition you'll choose is fine by me.

I am looking for ideas, methods or algorithm names, code is not necessary, but if you want i could provide images like this one. Happy to answer any practical questions.

EDIT: as requested here are other images, the first three come from the same set as the image above, the last ones come from another set, sometimes you have images with no clouds (but that's a complication I can do away with myself) : enter image description here enter image description hereenter image description here

enter image description here enter image description here enter image description hereenter image description here

$\endgroup$
3
  • $\begingroup$ Can you include two or three more images to help us figure out just how general the solution needs to be? $\endgroup$
    – Carl Lange
    Sep 9 at 10:08
  • $\begingroup$ @CarlLange done $\endgroup$
    – yfs
    Sep 9 at 10:17
  • 2
    $\begingroup$ You should probably deal with the noise by doing: ImageAdjust@TotalVariationFilter[img, 1] $\endgroup$
    – flinty
    Sep 9 at 13:07
9
$\begingroup$

Closest I can get with minimal input from the user. The key here is to pull an example object from one dataset to use for image correlation. (A strategy borrowed from this answer).

imgs = {
   "https://i.stack.imgur.com/uPOHl.jpg",
   "https://i.stack.imgur.com/oJCJO.jpg",
   "https://i.stack.imgur.com/XNRwG.jpg",
   "https://i.stack.imgur.com/1tvCA.jpg",
   "https://i.stack.imgur.com/6zhu3.jpg",
   "https://i.stack.imgur.com/9w3PR.jpg"};
i = Import /@ imgs;
object = ImageTake[i[[1]], {150, 200}, {225, 275}]

enter image description here

Here's how I isolate the objects:

ib = ColorNegate@
    Binarize[
     ImageCorrelate[#, object, NormalizedSquaredEuclideanDistance], 
     0.465] & /@ i
if = ImageAdjust@LaplacianGaussianFilter[#, 20] & /@ ib
Length@ComponentMeasurements[ColorNegate@Binarize@#, "Count"] & /@ if
ComponentMeasurements[ColorNegate@Binarize@#, "Centroid"] & /@ if

enter image description here

ib uses ImageCorrelate to find similar disks. I selected a level for Binarize that suited the entire dataset. Next, if is used to clean up the objects. A nice feature here is that the filter creates a halo around the objects that allows for relatively straightforward component isolation. (Which I learned from this answer) The next line just makes sure there are 7 objects detected in the image and then the centroids of the objects can found with ComponentMeasurements.

The center points found here can be used to determine distances. What's missing from this answer is an estimate of the intensity in each object. For that, the end user must make a decision on whether or not the objects are the same size. if they are, one could create a mask of fixed size at the centroid positions and count the intensity of the resulting images.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.