Function Repository Resource:

ContentAwareImageResize

Source Notebook

Perform content-aware image resizing by seam carving

Contributed by: Sander Huisman

ResourceFunction["ContentAwareImageResize"][image,width]

performs content-aware image resizing on image to have width width.

ResourceFunction["ContentAwareImageResize"][image,{height}]

performs content-aware image resizing on image to have height height.

ResourceFunction["ContentAwareImageResize"][image,{width,height}]

performs content-aware image resizing on image to have dimensions {width,height}.

ResourceFunction["ContentAwareImageResize"][image,"Width"]

returns a ContentAwareImageResizeObject that allows the width to be dynamically changed.

ResourceFunction["ContentAwareImageResize"][image,"Height"]

returns a ContentAwareImageResizeObject that allows the height to be dynamically changed.

ResourceFunction["ContentAwareImageResize"][ContentAwareImageResizeObject[],s]

returns an image of size s.

Details and Options

Content-aware image resizing uses seam carving or seam insertion to crop or to extend images. Important content in an image is found through "EnergyFunction". Low values are deleted before high values. Seams are found by a simple dynamic programming algorithm with a unit neighborhood.
The following options can be given:
"ProtectionMask"Nonemask that protects the content given in the mask
"RemovalMask"Nonemask that tries to remove content of the mask first
"DirectionOrder""WidthHeight"order of seam carving, either "WidthHeight" or "HeightWidth"
"EnergyFunction"GradientFilter[#,1,Method"ShenCastan"]&function to apply to the image that gives an importance value to each pixel
MethodAutomaticvalid options are "ForwardEnergy", "BackwardEnergy" and Automatic
"MaskMultiplier"10.04multiplier used for the masks
The option "ProtectionMask" should be a binary image with the same dimensions as the image.
The option "RemovalMask" should be a binary image with the same dimensions as the image.
The option "EnergyFunction" should be a function that returns a grayscale image in which the most important parts are white and the least important parts black.
Using "EnergyFunction", an importance is specified for each pixel:
Continuous seams are found from top to bottom or left to right using a neighborhood of 1 that minimizes the energy. The first continuous seam from top to bottom is highlighted in red:
By removing seams iteratively, the size of the image can be resized.
A removal mask is ignored when extending an image.
Extending an image is done in the same order that is used when removing seams. Except for that, seams are added as the mean values of the neighbors.
Changing the width and height is done by first seam carving along either the width or the height and then by seam carving along the height or the width.
The Method "BackwardEnergy" calculates the energy of the current image, then carves. "ForwardEnergy" looks at the energy after carving.

Examples

Basic Examples (2) 

Make the width of the image 200 pixels:

In[1]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/e19bd5c0-0515-42b0-aa88-9208f081ee8b"]
Out[1]=

Make the height of the image 120 pixels:

In[2]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/1fbff9b4-5564-4392-a1b8-61003d13527c"]
Out[2]=

Scope (4) 

Change the width and the height:

In[3]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/8978214e-a842-43e5-8573-669d9044d167"]
Out[3]=

Extend the image by 100 pixels in the width:

In[4]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/09ececc5-9034-4a5a-8093-1f014321f824"]
Out[4]=

Extend the image by 50 pixels in the height:

In[5]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/26d036e9-d6aa-46cd-a55a-4b752f64946b"]
Out[5]=

Make a ContentAwareImageResizeObject for the width:

In[6]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/195c96a3-f131-4bdf-bb52-c3124620ca0d"]
Out[6]=

Dynamically change the width in real time:

In[7]:=
Manipulate[
 ResourceFunction["ContentAwareImageResize"][cairo, j], {{j, cairo["MaxSize"]/2}, Round[0.25 cairo["MaxSize"]], Round[0.75 cairo["MaxSize"]], 1}]
Out[7]=

Options (8) 

ProtectionMask (2) 

Change the width while protecting the booby:

In[8]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/1502dbd4-dfcc-4170-bb97-1a454012e135"]
Out[8]=

Without a mask, the main subject can be deformed because the background also has many details:

In[9]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/a642bc11-3875-4219-b3a4-ef400baf5542"]
Out[9]=

Change the height while protecting the booby:

In[10]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/a309ac49-fb58-493a-817f-9cc89d438d78"]
Out[10]=

RemovalMask (2) 

Remove a feature of a photo:

In[11]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/8fb9c7b4-cce4-4e66-95ee-bae5fbdda6f5"]
Out[11]=

Having a removal mask while having a protection mask is possible:

In[12]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/4dad6984-8b30-4c2d-b78f-b9b9f6fef014"]
Out[12]=

DirectionOrder (1) 

Change the order of removal:

In[13]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/78dfa397-3673-4d9d-96c1-129a6692068f"]
Out[13]=

Method (1) 

Change the method and compare them:

In[14]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/7ef5bd23-48d1-4aef-a929-4e85ce51624d"]
Out[14]=

EnergyFunction (1) 

Change the function that provides the importance of the pixels:

In[15]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/7eab7c12-b103-4159-8139-33c9cc287a71"]
Out[15]=

MaskMultiplier (1) 

Give an importance to the mask and see its impact:

In[16]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/88b84651-5ad5-4515-b791-cb1a66bca40f"]
Out[16]=

Applications (1) 

Make a series of photos with a variety of widths suitable for websites for different devices:

In[17]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/1b5df419-0659-4695-9caa-77aa25f94429"]
Out[17]=

Properties and Relations (1) 

Compare to other methods of image resizing:

In[18]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/8952eaa0-02c6-4201-b3ac-c73a136e456d"]
Out[18]=

Possible Issues (3) 

Without a mask, a face might be considered smooth and without much energy:

In[19]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/e01b6ee8-24df-4e5b-a465-4fc59d6581de"]
Out[19]=

Use a mask to protect the body:

In[20]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/585ab949-2f75-4631-8ba1-c7ff4ab23ed0"]
Out[20]=

The width has to be a positive integer:

In[21]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/2f400dd6-2f69-424c-b69a-12b6e65a0d13"]
Out[21]=

One cannot extend beyond twice the original width:

In[22]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/15b24098-97a7-4326-9fd6-c7f956028a34"]
Out[22]=

Neat Examples (2) 

Trim or extend an image:

In[23]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/e66481d2-208d-40a9-ad8e-58cd349dcaf2"]
Out[23]=

Change the height dynamically:

In[24]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/98723344-a159-4b4f-87a6-499bf356d6c0"]
Out[24]=

Publisher

SHuisman

Version History

  • 1.0.0 – 06 November 2019

Source Metadata

Related Resources

Author Notes

Does not support 3D images. Does not support images with alpha channels.

License Information