How to crop image using Rectangle?

I use ImageBoundingBoxes to get the bounding boxes of objects in an image. I then want to crop out each object and I tried directly passing the Rectangle objects from ImageBoundingBoxes to ImageTake, but it does not work. I also tried converting the rectangle to a list of points by doing

{rect[[1]],rect[[2]]}


and passing that to ImageTake, but that also did not work, probably because ImageTake expects row and col number, which start from the top left corner, whereas Rectangle contains x and y which start from the bottom left corner. How can I convert Rectangle to a form that I can pass to ImageTake so that I can crop out the part of the image that the bounding box covers?

EDIT: I looked at ImageTrim and wrote the following function to to get a list of the four corners of a Rectangle object so that it can be passed to ImageTrim:

rectToList[rect_] := {rect[[1]], rect[[2]], {rect[[1, 1]], rect[[2, 2]]}, {rect[[2, 1]], rect[[1, 2]]}};


Then, I was able to crop out the bounding box portion as follows:

croppedImg = ImageTrim[img,rectToList[rect]];


Is this the best way to crop out the bounding box portion of an image?

• Have you seen ImageTrim? Mar 11 at 21:36
• @C.E. Thank you for the suggestion. ImageTrim requires a list of points, so I wrote a simple function that makes a list of the four corners of the rectangle. Is this the best way? Mar 11 at 21:49
• I think it can work to pass the rectangles. ImageTrim can, as the documentation says, take a region of interest (or a list of regions). Consider the examples under "Application" for example. Say, the FindFaces example. FindFaces returns Rectangle objects and yet it works. Mar 11 at 21:54
• @C.E. Yes, you are right. I forgot that FindFaces returned Rectangle. Thanks. Mar 12 at 6:45

As C.E. noted, easiest way is to use ImageTrim[image, rectangles] as ImageTrim accepts Rectangle objects as the trimming spec.

You can also to use ImageTake by converting rectangle coordinates to a form that can be used row and column specs in ImageTake:

ClearAll[imageTake]

imageTake[im_, r : {__Rectangle}] :=  Module[{rowscols =
Map[Apply[{ImageDimensions[im][[2]] + 1 - Reverse@#, #2} &]@* Reverse@*Transpose]@
(r /. Rectangle -> List)},
ImageTake[im, ##] & @@@ rowscols]


Example: Using the image from the first example in ImageBoundingBoxes:

img = Import["https://i.stack.imgur.com/8xQHy.png"]


rectangles = ImageBoundingBoxes[img, Entity["Species", "Class:Aves"]]

 {Rectangle[{130.885, 18.5558}, {166.549, 92.807}],
Rectangle[{91.2438, 38.0867}, {130.923, 101.634}]}

imageTake[img, rectangles] // Map[ImageResize[#, 300] &]


We get the same result using ImageTrim directly with rectangles:

ImageTrim[img, rectangles] // Map[ImageResize[#, 300] &]

 same picture.