Skip to main content
added 518 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
(* Perform image manipulation steps, feeding from one to another. *)
(* You can replace a "//" with "// Echo //" to see an intermediate value. *)
MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
    Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
  (* Measure component centroids on the manipulated image. *)
  ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
 Function[v, 
  (* Select valid edges from all pairs of components:
     - those whose edge length is less than 300, and
     - at most 4 values of 400 sampled along the edge have a value < 0.25 *)
  Select[Subsets[v, {2}],
     EuclideanDistance @@ # < 300 && Count[
        Table[
         Min@PixelValue[imgCount[Table[Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 0.0025}],
          0.0025}], _?(# < 0.25 &)] < 5 &] // 
   (* Overlay the graph on top of the original image. *)
   Show[img,
     (* Construct a graph object with vertices on component centroids,
        and edges as filtered by the Select expression. *) 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v, 
      VertexStyle -> Red, VertexSize -> 1/2], ImageSize -> Medium] &]
g = (MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
      Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
    ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
   Function[v, 
    Select[Subsets[v, {2}], 
       EuclideanDistance @@ # < 300 && 
        Count[Table[
           Min@PixelValue[imgCount[Table[Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 0.0025}],
            0.0025}], _?(# < 0.25 &)] < 5 &] // 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v] &])
(* Perform image manipulation steps, feeding from one to another. *)
(* You can replace a "//" with "// Echo //" to see an intermediate value. *)
MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
    Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
  (* Measure component centroids on the manipulated image. *)
  ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
 Function[v, 
  (* Select valid edges from all pairs of components:
     - those whose edge length is less than 300, and
     - at most 4 values of 400 sampled along the edge have a value < 0.25 *)
  Select[Subsets[v, {2}], EuclideanDistance @@ # < 300 && Count[
        Table[
         Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
          0.0025}], _?(# < 0.25 &)] < 5 &] // 
   (* Overlay the graph on top of the original image. *)
   Show[img,
     (* Construct a graph object with vertices on component centroids,
        and edges as filtered by the Select expression. *) 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v, 
      VertexStyle -> Red, VertexSize -> 1/2], ImageSize -> Medium] &]
g = (MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
      Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
    ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
   Function[v, 
    Select[Subsets[v, {2}], 
      EuclideanDistance @@ # < 300 && 
        Count[Table[
           Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
            0.0025}], _?(# < 0.25 &)] < 5 &] // 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v] &])
(* Perform image manipulation steps, feeding from one to another. *)
(* You can replace a "//" with "// Echo //" to see an intermediate value. *)
MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
    Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
  (* Measure component centroids on the manipulated image. *)
  ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
 Function[v, 
  (* Select valid edges from all pairs of components:
     - those whose edge length is less than 300, and
     - at most 4 values of 400 sampled along the edge have a value < 0.25 *)
  Select[Subsets[v, {2}],
     EuclideanDistance @@ # < 300 &&
      Count[Table[Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 0.0025}],
       _?(# < 0.25 &)] < 5 &] // 
   (* Overlay the graph on top of the original image. *)
   Show[img,
     (* Construct a graph object with vertices on component centroids,
        and edges as filtered by the Select expression. *) 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v, 
      VertexStyle -> Red, VertexSize -> 1/2], ImageSize -> Medium] &]
g = (MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
      Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
    ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
   Function[v, 
    Select[Subsets[v, {2}],
       EuclideanDistance @@ # < 300 &&
        Count[Table[Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 0.0025}],
         _?(# < 0.25 &)] < 5 &] // 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v] &])
added 518 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95

If you want the graph object instead of a visualization, you canFollowing variant just remove Show[img, ..., ImageSize -> Medium] aroundgenerates the graph Graphg expression:

g = (MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
      Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
    ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
   Function[v, 
    Select[Subsets[v, {2}], 
      EuclideanDistance @@ # < 300 && 
        Count[Table[
           Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
            0.0025}], _?(# < 0.25 &)] < 5 &] // 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v] &])

. This object is suitable for Mathematica-based graph manipulation.. on which you can perform graph operations:

CommunityGraphPlot[g]

enter image description here

If you want the graph object instead of a visualization, you can just remove Show[img, ..., ImageSize -> Medium] around the Graph expression. This object is suitable for Mathematica-based graph manipulation.

Following variant just generates the graph g:

g = (MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
      Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
    ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
   Function[v, 
    Select[Subsets[v, {2}], 
      EuclideanDistance @@ # < 300 && 
        Count[Table[
           Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
            0.0025}], _?(# < 0.25 &)] < 5 &] // 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v] &])

... on which you can perform graph operations:

CommunityGraphPlot[g]

enter image description here

added 836 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95

Another starting point, where the objects being more or less fixed size disks is used ad hoc to measure their centroids as components after some mangling, and those which are close enough to each other are connected in the graph if out of sample of four hundred points along the edge at most four are not "white."

Image is in the variable img and plenty of magic constants are employed. (If it's not otherwise obvious, I have to make it explicit: having such hand-picked constants as 0.9, 40, 55, 300, 0.0025 or even 0.25 or 5 is definitely a weakness, not a strong point of a solution.)

(* Perform image manipulation steps, feeding from one to another. *)
(* You can replace a "//" with "// Echo //" to see an intermediate value. *)
MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
    Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
  (* Measure component centroids on the manipulated image. *)
  ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
 Function[v, 
  (* Select valid edges from all pairs of components:
     - those whose edge length is less than 300, and
     - at most 4 values of 400 sampled along the edge have a value < 0.25 *)
  Select[Subsets[v, {2}], EuclideanDistance @@ # < 300 && Count[
        Table[
         Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
          0.0025}], _?(# < 0.25 &)] < 5 &] // 
   (* Overlay the graph on top of the original image. *)
   Show[img,
     (* Construct a graph object with vertices on component centroids,
        and edges as filtered by the Select expression. *) 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v, 
      VertexStyle -> Red, VertexSize -> 1/2], ImageSize -> Medium] &]

enter image description here

If you want the graph object instead of a visualization, you can just remove Show[img, ..., ImageSize -> Medium] around the Graph expression. This object is suitable for Mathematica-based graph manipulation.

Another starting point, where the objects being more or less fixed size disks is used ad hoc to measure their centroids as components after some mangling, and those which are close enough to each other are connected in the graph if out of sample of four hundred points along the edge at most four are not "white."

Image is in the variable img and plenty of magic constants are employed. (If it's not otherwise obvious, I have to make it explicit: having such hand-picked constants as 0.9, 40, 55, 300, 0.0025 or even 0.25 or 5 is definitely a weakness, not a strong point of a solution.)

MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
    Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
  ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
 Function[v, 
  Select[Subsets[v, {2}], EuclideanDistance @@ # < 300 && Count[
        Table[
         Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
          0.0025}], _?(# < 0.25 &)] < 5 &] // 
   Show[img, 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v, 
      VertexStyle -> Red, VertexSize -> 1/2], ImageSize -> Medium] &]

enter image description here

Another starting point, where the objects being more or less fixed size disks is used ad hoc to measure their centroids as components after some mangling, and those which are close enough to each other are connected in the graph if out of sample of four hundred points along the edge at most four are not "white."

Image is in the variable img and plenty of magic constants are employed. (If it's not otherwise obvious, I have to make it explicit: having such hand-picked constants as 0.9, 40, 55, 300, 0.0025 or even 0.25 or 5 is definitely a weakness, not a strong point of a solution.)

(* Perform image manipulation steps, feeding from one to another. *)
(* You can replace a "//" with "// Echo //" to see an intermediate value. *)
MorphologicalBinarize[img, 0.9] // Blur[#, 40] & // 
    Binarize[#, 0.9] & // HitMissTransform[#, DiskMatrix[55]] & // 
  (* Measure component centroids on the manipulated image. *)
  ComponentMeasurements[#, "Centroid"][[All, 2]] & // 
 Function[v, 
  (* Select valid edges from all pairs of components:
     - those whose edge length is less than 300, and
     - at most 4 values of 400 sampled along the edge have a value < 0.25 *)
  Select[Subsets[v, {2}], EuclideanDistance @@ # < 300 && Count[
        Table[
         Min@PixelValue[img, {t, 1 - t}.#], {t, 0, 1, 
          0.0025}], _?(# < 0.25 &)] < 5 &] // 
   (* Overlay the graph on top of the original image. *)
   Show[img,
     (* Construct a graph object with vertices on component centroids,
        and edges as filtered by the Select expression. *) 
     Graph[v, UndirectedEdge @@@ #, VertexCoordinates -> v, 
      VertexStyle -> Red, VertexSize -> 1/2], ImageSize -> Medium] &]

enter image description here

If you want the graph object instead of a visualization, you can just remove Show[img, ..., ImageSize -> Medium] around the Graph expression. This object is suitable for Mathematica-based graph manipulation.

added 1 character in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
deleted 2 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 2 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
deleted 259 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 171 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 8 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
oops
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 4 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 24 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 24 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
added 41 characters in body
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading
Source Link
kirma
  • 19.1k
  • 1
  • 55
  • 95
Loading