7
$\begingroup$

The question is link this post.But It more hard than that I think.That time I count it by contrast,computer is good at it.But this time I wanna count the little pane's proportion,Maybe we can make a area threshold to do it. There are some sample image

pic1$\qquad$pic2$\qquad$pic3$\qquad$pic4$\qquad$pic5

I didn't upload it,it'll make the page get very long.The small pane is our target.I make a lable "Yes" on it.

Mathematica graphics

In the link case I can use Mathematica give a try.But this time I make some low precision effect.If we just use simple method like Closing it will be very bad.like

img = Import["https://i.stack.imgur.com/OO36H.jpg"];
(log = LaplacianGaussianFilter[img, 2]) // ImageAdjust;
bin = MorphologicalBinarize[log, {0.005, 0.06}]

Mathematica graphics

Hightlight that we get
HighlightImage[img, ColorNegate@Closing[bin, 7]]

Mathematica graphics

$\endgroup$
1
  • $\begingroup$ Yes.But the last image have a low precision $\endgroup$
    – yode
    Mar 31, 2016 at 9:07

2 Answers 2

16
+200
$\begingroup$

I'm not 100% sure what you want. Loosely speaking, your images look like there are hills and valleys, with light coming from the left. And I think you're looking for the "valleys" in that landscape.

A mathematical model for this would be: There's a "height" (or "depth") for every pixel, and the image you have is the gradient (in X-direction) of that height field. So we want to find a height field, that, when convolved with a gradient filter kernel, reproduces your source image.

enter image description here

(this plot shows one line of the input and result images below)

This problem is called "Deconvolution", and Mathematica has a built-in function for it: ImageDeconvolve.

Let's try this with one of your images:

urls = {"https://i.stack.imgur.com/LiQsY.jpg", 
   "https://i.stack.imgur.com/CRkrS.jpg", 
   "https://i.stack.imgur.com/cXTRq.jpg", 
   "https://i.stack.imgur.com/KUcKE.jpg", 
   "https://i.stack.imgur.com/OO36H.jpg"};
img = ImageTake[ColorConvert[Import[urls[[1]]], "Grayscale"], 500, 500];

I'm using a derivative of Gaussian filter kernel for the deconvolution, and (determined by trial and error) the "Wiener" method:

deconv = ImageAdjust@
  ImageDeconvolve[img, GaussianMatrix[3, {0, 1}], Method -> "Wiener"]

enter image description here

This doesn't look too impressive, but if you binarize it (default threshold, no manual tinkering needed):

HighlightImage[img, Binarize[deconv]]

enter image description here

You see that we get a pretty good estimate for the "hills". Getting the "valleys" is just as easy:

HighlightImage[img, 
 Erosion[ColorNegate[Binarize[deconv]], DiskMatrix[5]]]

enter image description here

Here's the result for the full images:

Monitor[
  Do[
   img = Image[ColorConvert[Import[urls[[i]]], "Grayscale"], 
     ImageSize -> 1280];
   deconv = 
    ImageAdjust@
     ImageDeconvolve[img, GaussianMatrix[3, {0, 1}], 
      Method -> "Wiener"];
   Export["so_Valleys" <> ToString[i] <> ".jpg", 
    HighlightImage[img, 
     Erosion[ColorNegate[Binarize[deconv]], DiskMatrix[5]]]]
   , {i, Length[urls]}], i];

enter image description here

enter image description here

enter image description here

In the next two images, some of the "valleys" are brighter than the others, so the "brightness is gradient of height" model results in "slanted" areas: That's why these valleys are slightly larger on one side

enter image description here

enter image description here

$\endgroup$
1
  • $\begingroup$ Your code always inspired me deeply. $\endgroup$
    – yode
    Apr 8, 2016 at 14:02
5
$\begingroup$

This is kinda slow in my mac so before spending more time on it I rather have some comments from OP.

The basic idea is that I want to amplify the gradient on the image and then separate the areas of constant value.

img = Import["https://i.stack.imgur.com/LiQsY.jpg"]
img2 = Import["https://i.stack.imgur.com/OO36H.jpg"]

xx2 =  Module[{im = ImageTake[img, {800, 400}, {400, 800} ]}, 
  ImageAdd[im, GaussianFilter[GradientFilter[ImageAdd[im,
       GaussianFilter[GradientFilter[im, .5], 0]], .5], 0]]]

I don't know how to explain this but seems to work. I want to add noise to the areas where there is a lot of variation so I can separate better later.

Now I want to have the image in colour, since looks nicer and gives me the sense of height.

colorImg = 
 ListContourPlot[ImageData[xx2, DataReversed -> True], 
  ColorFunction -> Hue, Contours -> 5, Frame -> False, 
  AspectRatio -> 1, ImageSize -> 401]

enter image description here

It's starting to look like something. Now color separate

ColorSeparate@colorImg 

enter image description here

For the large "ponds" of the other picture you need to take another channel btw.

GaussianFilter[%[[2]], 3]

enter image description here

Binarize[%, .95]

enter image description here

And finally check it out.

HighlightImage[ImageTake[img, {800, 400}, {400, 800} ], %]

enter image description here enter image description here

You may need to get some reference images to check how much we are understatimating due to edge thickness. It also looks like your tip is bent in the microscope, there is this "shadow" to the left...

To improve the quality maybe it would be nice to star form the clusters I found and increase them till they touch a boundary. I imagine this as a landscape and you want to pour ink on the lagoons. Looks fun.

$\endgroup$
1
  • $\begingroup$ Thanks for your try.But the precision seem to be improved. $\endgroup$
    – yode
    Apr 8, 2016 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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