# Is there a SubImageApply?

Given an image and a subimage (as a rectangle or pixel ranges):

img = ExampleData[{"TestImage", "Lena"}];
f = FindFaces[img]; HighlightImage[img, f]


How would one apply operations just that sub-image, leaving the rest of the pixels unchanged?

(* would maybe be something like this *)
ImageConvolve[img, BoxMatrix[1]/11, "MapAt" -> f]
ImageApply[Max, img, "Subimage" -> f]


Is there a built-in or slick way to this (without resorting to ImageData and MapAt)? I thought there was something like this added in 12, but was perhaps mistaken. If not, ImageMapAt or ImageApplyAt or some such thing would surely make a nice repository function.

• For that matter, doesn't look like FindFaces returns index slices, only less useful rectangles. – M.R. Aug 20 '19 at 11:24

Assuming f matches {__Rectangle}:

subImageApply[image_Image, sub : {__Rectangle}, filter_] := Fold[
ImageCompose[#, #2[[1]], #2[[2]], {0, 0}] &
, image
, { filter @ ImageTrim[image, #],  #[[1]] } & /@ sub
]

subImageApply[img, f, Blur[#, 12] &]


You can use ImageConvolve or whatever you need instead of Blur.

Fold is there to account for multiple rectangles.

• Elegant! Thanks :) I think if they just added "Masking" option to every image operation that would be super – M.R. Aug 20 '19 at 11:44
• @M.R. You are welcome. I expected it to be easier but that is fine enough I guess. Otoh image-processing is not my area so maybe I missed something. – Kuba Aug 20 '19 at 11:45
• ImageApply and ImageFilter take Masking option. – Piotr Wendykier Aug 26 '19 at 16:47