Skip to main content
added 3558 characters in body; edited title
Source Link
Markus Roellig
  • 7.8k
  • 2
  • 31
  • 55

Detect sub figures and split automatically(automatically?)

EDIT

Following up on the help by C.E. here is my improved approached. I also used some input from this question/answers. It is not automatic yet, but I got sufficiently nice results.

Starting from the aligned and padded pieces

images = Flatten@ImagePartition[ ImagePad[img, {{10, 15}, {15, 10}}, White], {xdim/4 + 20, ydim/4 + 20}, {xdim/4, ydim/4} ]; aligned = ImageAlign[images, Method -> "FourierBlurInvariant", TransformationClass -> "Translation"]; 

Note, that I added the second argument White to ´ImagePad` to prevent the default padding with black pixel. I then start by visually checking the correct identification of the vertical frame lines

HighlightImage[#, ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[\[Pi]/2, 0, {2, 0}, Pi/2, {0, 2}]], {0.02, 0.05}], 0.4]& /@ aligned 

enter image description here

The parameter 0.4 in ImageLines can be used to tune the identification. Now I take the (common) column number of the two vertical lines:

vlines = Sort[{Min[#[[1]]], Max[#[[2]]]}] & /@ (( ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[\[Pi]/2, 0, {2, 0}, Pi/2, {0, 2}]], {0.02, 0.05}], 0.4][[All, 1, All, 1]] & /@ aligned) (* {{17.1989, 278.839}, {17.1989, 277.836}, {17.0842, 277.951}, {18.0871, 277.951}, {17.0842, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}, {18.0871, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}} *) 

17 and 278 seems to be the common vertical position. Manually padding a little for sufficient image quality I get

 vcropped = ImageTake[#, {1, -1}, {16, 277}] & /@ aligned 

enter image description here

As we see, all vertical frame axes are conserved and aligned. The same approach for the horizontal axes

 hlines = Sort[{ Min[#[[1]]], Max[#[[2]]]}] & /@ ((ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[0, 0, {2, 0}, Pi/2, {0, 2}]], {0.05, 0.02}], 0.4])[[ All, 1, All, 2]] & /@ vcropped) (* {{10.3036, 215.695}, {10.3036, 215.695}, {10.3036, 215.695}, {10.3036, 215.695}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {11.3055, 216.696}, {11.3055, 216.696}, {11.3055, 216.696}, {11.3055, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}}*) HighlightImage[#, ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[0, 0, {2, 0}, Pi/2, {0, 2}]], {0.05, 0.02}], 0.4]] & /@ vcropped 

enter image description here

 hcropped = ImageTake[#, {11, 217}, {1, -1}] & /@ vcropped 

enter image description here

The frames are properly conserved. We realign everthing and the result is ok.

 alignedCropped = ImageAlign[hcropped, TransformationClass -> "Translation"]; 

enter image description here

Detect sub figures and split automatically

Detect sub figures and split (automatically?)

EDIT

Following up on the help by C.E. here is my improved approached. I also used some input from this question/answers. It is not automatic yet, but I got sufficiently nice results.

Starting from the aligned and padded pieces

images = Flatten@ImagePartition[ ImagePad[img, {{10, 15}, {15, 10}}, White], {xdim/4 + 20, ydim/4 + 20}, {xdim/4, ydim/4} ]; aligned = ImageAlign[images, Method -> "FourierBlurInvariant", TransformationClass -> "Translation"]; 

Note, that I added the second argument White to ´ImagePad` to prevent the default padding with black pixel. I then start by visually checking the correct identification of the vertical frame lines

HighlightImage[#, ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[\[Pi]/2, 0, {2, 0}, Pi/2, {0, 2}]], {0.02, 0.05}], 0.4]& /@ aligned 

enter image description here

The parameter 0.4 in ImageLines can be used to tune the identification. Now I take the (common) column number of the two vertical lines:

vlines = Sort[{Min[#[[1]]], Max[#[[2]]]}] & /@ (( ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[\[Pi]/2, 0, {2, 0}, Pi/2, {0, 2}]], {0.02, 0.05}], 0.4][[All, 1, All, 1]] & /@ aligned) (* {{17.1989, 278.839}, {17.1989, 277.836}, {17.0842, 277.951}, {18.0871, 277.951}, {17.0842, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}, {18.0871, 277.951}, {17.1989, 277.836}, {17.0842, 277.951}, {17.1989, 277.836}} *) 

17 and 278 seems to be the common vertical position. Manually padding a little for sufficient image quality I get

 vcropped = ImageTake[#, {1, -1}, {16, 277}] & /@ aligned 

enter image description here

As we see, all vertical frame axes are conserved and aligned. The same approach for the horizontal axes

 hlines = Sort[{ Min[#[[1]]], Max[#[[2]]]}] & /@ ((ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[0, 0, {2, 0}, Pi/2, {0, 2}]], {0.05, 0.02}], 0.4])[[ All, 1, All, 2]] & /@ vcropped) (* {{10.3036, 215.695}, {10.3036, 215.695}, {10.3036, 215.695}, {10.3036, 215.695}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {11.3055, 216.696}, {11.3055, 216.696}, {11.3055, 216.696}, {11.3055, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}, {10.3036, 216.696}}*) HighlightImage[#, ImageLines[ MorphologicalBinarize[ GaussianFilter[#, 3, Switch[0, 0, {2, 0}, Pi/2, {0, 2}]], {0.05, 0.02}], 0.4]] & /@ vcropped 

enter image description here

 hcropped = ImageTake[#, {11, 217}, {1, -1}] & /@ vcropped 

enter image description here

The frames are properly conserved. We realign everthing and the result is ok.

 alignedCropped = ImageAlign[hcropped, TransformationClass -> "Translation"]; 

enter image description here

Became Hot Network Question
Tweeted twitter.com/StackMma/status/1186386796495691778
Source Link
Markus Roellig
  • 7.8k
  • 2
  • 31
  • 55

Detect sub figures and split automatically

I would like to take a large figure showing a sequence of individual plots and automatically split the into series of images showing the individual sub-plots (to be exported as animated GIF later). So far I do it manually. The large image is cut from a PDF (called img ):

enter image description here

I manually crop the image:

img = ImageTake[img, {10, 837}, {2, 1049}] id = ImageDimensions[img] (* {1048, 828} *) 

When I partition the image I miss the frames on some sides because they are only 1 pixel wide.

imgs = Partition[Flatten[ImagePartition[img, Round[id/4]]], 1] 

enter image description here

Followed by the export as animated GIF:

Export[<insert file name here>, imgs, "GIF","AnimationRepetitions" -> Infinity] 

enter image description here

I would be grateful for any input that can automate the process and improve the quality of the final frames.