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
):
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]
Followed by the export as animated GIF:
Export[<insert file name here>, imgs, "GIF","AnimationRepetitions" -> Infinity]
I would be grateful for any input that can automate the process and improve the quality of the final frames.
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
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
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
hcropped = ImageTake[#, {11, 217}, {1, -1}] & /@ vcropped
The frames are properly conserved. We realign everthing and the result is ok.
alignedCropped = ImageAlign[hcropped, TransformationClass -> "Translation"];