5
$\begingroup$

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

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

enter image description here

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]

enter image description here

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.

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

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] &]

enter image description here

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

Fold is there to account for multiple rectangles.

$\endgroup$
  • $\begingroup$ Elegant! Thanks :) I think if they just added "Masking" option to every image operation that would be super $\endgroup$ – M.R. Aug 20 at 11:44
  • $\begingroup$ @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. $\endgroup$ – Kuba Aug 20 at 11:45
  • $\begingroup$ ImageApply and ImageFilter take Masking option. $\endgroup$ – Piotr Wendykier Aug 26 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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