I have a PDF file that contains 3 pages of microphotographs that are subdivided into subimages of several individual micrographs. For the first two pages the individual photomicrographs are arranged in a 3x2 array (labeled A-F) whereas on the last page, the last element of what would be an another 3x2 array is missing so that only micrographs labeled A-E appear.

I seek to save these micrographs (array elements) each as a single image file that can be subsequently associated with data from the image captions. When imported the original files contain a single image each so I seek to subdivide each page into its natural component micrographs minimizing retaining maximum resolution with minimal distortion of the proportional heights and widths.

Here is a down sampled version of the 6 micrographs on the first page:


Using the following, I nearly succeed in partitioning the single image containing 6 micrographs arranged in 3 rows of 2 micrographs each so that each sub image can be saved as an individual file and associated with the appropriate figure captions, eventually all bundled within a Dataset.

subimages = Flatten[ImagePartition[image6, {210/3}]]

enter image description here

However, note that the two micrographs labeled "C" and "D" actually contain a small portion of the pixels in the previous two micrographs. I've attempted to alter the value passed for the individual image widths, but increasing or decreasing this value typically as well as playing with Ceiling/Floor functions and padding results either in an additional number of unwanted partitions, or too few partitions in which some of the individual micrographs are lost. It seems this arises from the individual micrographs not being all the same image dimension. Similar results emerge when using the larger original files, although the values for widths are necessarily larger.

How can one partition the original image so that the desired effect is achieved even when the sub images are not uniformly sized?

Ideally, an automatic solution is sought that does not require manual tweaking in such situations. I have tried to segment the original image into a list of components following the suggestions for questions 35249 and 109154, but using either MorphologicalComponents[] or ImageForestingComponents[] fail to get all parts of all desired sub images. Usually 4 or 5 of 6 micrographs, can be obtained but unfortunately both functions break some individual micrographs into many undesirable smaller components. These not easily joined to recreate the missing "whole" components sought, because the components of these missing elements typically appear in arbitrary order and there may be several hundreds or thousands of them. Thus, making them difficult to identify and recompose into a single sub image (micrograph).

Croping and then arranging cropped parts into a list might work, but I can't figure out how to tell ImageCrop how to determine the border dimensions of the desired sub images before the command is executed without considerable trial and error that needs to be avoided to achieve a fully automated process.

  • $\begingroup$ are the image labels separately available or are they extracted from the images themselves? $\endgroup$
    – EstabanW
    Aug 15, 2021 at 11:35
  • $\begingroup$ Image labels appear in the sub images A-F or A-E, etc. The captions are in text still within the PDF document containing the images but not yet addressed, since want first to be able to segment sub-images properly and then start the task of associating the labels with the text in the figure captions. $\endgroup$ Aug 16, 2021 at 20:23

1 Answer 1


I start with an image panel. You can use your example.

img = Import["C:\\Work\\typical_image_panel.jpg"];

enter image description here

The main reason I chose this image using Google search is that it has labels and all subpanels have varying degrees of feature granularity. It may or may not be important for your case. Then I ran the following command; (more experimentation required with thresholds). You can run this in steps to see what's going on at each step.

t1 = MorphologicalBinarize[img, {0.96, 0.96}] // ColorNegate // ImageSubtract[img, #] & // DeleteSmallComponents // ColorNegate

enter image description here

The label (c) is attached with a few small pixels and was not removed highlighting the complexity of such tasks, but let's keep going.

HighlightImage[img, ImageLines[GradientFilter[t1, 1], 0.1, 0.15]]

The ImageLines[..] above can be evaluated separately to get these line parameters for further processing.

You can read this excellent article on perimetric complexity if you haven't done so already. I hope this answer provides you some pointers to get started.

enter image description here


Your Answer

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

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