image retargeting seam carving

18
IMAGE RETARGETING: SEAM CARVING ECE 533 Image Processing Project 12/20/2012 University of Wisconsin-Madison Shiwei Zhou

Upload: bharathisenthil

Post on 03-Jan-2016

44 views

Category:

Documents


3 download

DESCRIPTION

image retargeting seam carving is an ieee paper

TRANSCRIPT

Page 1: Image Retargeting Seam Carving

IMAGE RETARGETING: SEAM CARVING ECE 533 Image Processing Project 12/20/2012 University of Wisconsin-Madison Shiwei Zhou

Page 2: Image Retargeting Seam Carving

1

1. Introduction

Nowadays with the increasing number of display devices, web contents can be displayed with

various sizes for different devices. This imposes new demands on digital media which require

designers to create different alternatives and design different layouts for these devices [1].

Currently, page layout and text can be dynamically changed according to the size of the display

devices through some standards like HTML. However, it is still almost impossible to deform

images to fit for different layouts, due to its rigidity in size. Therefore, there is great need for

displaying images on various media like cell phones or PDAs without distortion.

Normal scaling does not work very well because content of the image have been distorted, which

makes the image less visually pleasing. Cropping also has certain drawbacks since some of the

important image contents could have been discarded. Hence, it is necessary to develop a more

effective resizing approach which considers the image contents instead of geometric constraints

[1]. Avidan and Shamir (2007) has proposed such an effective algorithm for image resizing that

tries to get rid of or add to regions of the image which are not content-aware. Figure 1.1

illustrates an example of different approaches to resize an image.

Original Image Normal Scaling

Cropping Seam Carving

Figure 1.1 Different Approaches for Image Resizing [2]

Page 3: Image Retargeting Seam Carving

2

2. Approach

The essence of seam carving is to find the optimal seam that is least content-aware in the image.

For image of size n × m, a vertical seam is defined as a set of pixels of the form 1

,n

ii S i

where S is a mapping S: [1, … , n] → [1, … , m], such that 1 1S i S i for all i, i.e. all the

pixels along the path are 8-connected. Similarly, horizontal seam is defined as the set

1

,m

iS i i

such that 1 1S i S i for all i. The process on vertical seams and horizontal

seams are similar, hence to avoid redundancy, the following parts will mainly focus on vertical

seams.

To find a continuous path across the image that can go through areas of image that are less

content-aware and avoid major content of the image, it is necessary to search for seams with

minimal energy. The basic energy function commonly used for an image is defined as the total

gradient of the image: 1

I Ie I

x y

, which can be approximated for each pixel (i,j) by

, 1, , , 1 ,e i j x i j x i j x i j x i j . There are several possible image importance

measures, such as entropy, segmentation, Histogram of Gradients (HoG), or other norms of total

gradient [3]. For this project, I will use e1 as the energy function. e(i,j) is also known as the cost

of a single pixel at (i,j), hence the cost of a seam is defined as ,ke k S k for vertical seam

and ,ke S k k for horizontal seam. Therefore, given an energy function e, the optimal seam

is the one that minimizes the cost of the seam.

The optimal seam can be found using dynamic programming. Given e and a direction, say

vertical, we define the cumulative minimum energy M as , min ,end

S i j k iM i j e k S k

,

which is the minimum cost of the vertical seam starting from pixel (i,j) and going down to the

bottom of the image. Thus the minimum entry of the first row of M indicates the final pixel of

the optimal seam that we are searching for. In order to find the whole optimal seam, we can

simply trace back using the following dynamic programming algorithm:

1) The last row of M is equal to the last row of e, i.e. , ,M n j e n j

2) For 1 ≤ i ≤ n – 1 and 1 ≤ j ≤ m,

, , min 1, 1 , 1, , 1, 1M i j e i j M i j M i j M i j

3) For pixels at edges of the image, we can replace the above equation with

,1 ,1 min 1,1 , 1,2M i e i M i M i

or ,1 ,1 min 1, , 1,1 , 1,2M i e i M i j M i M i

Page 4: Image Retargeting Seam Carving

3

Once we have found the optimal seam, we can either shrink the image or enlarge the image

without distorting the major content of image. For shrinking the image, we just need to search

the optimal seams and remove them from the image. For stretching the image, it is necessary to

first find the optimal seams that need to be removed, then duplicate them and insert at the right

side of those seams. Details about the implementation will be discussed in later sections.

3. Work Performed

For MATLAB implementation, the main function of the whole program is called ImageRetarget

and all other functions are called in this function. Firstly the energy function named energy

should be implemented. Here I calculate the total gradient using a function called gradient. Also

since the original image is RBG image, a function called rgb2gray is used to convert it into gray

image, so that the computation complexity is reduced. The following MATLAB codes show how

to implement the energy function. Figure 3.1 displays the gradient of an example image. Dark

areas mean low gradient, and bright areas mean high gradient, which represent relatively

important regions.

Function energy:

Figure 3.1 Energy/Gradient of the Image

function E = energy(img)

% this function calculates the energy/total gradient of the image

[fx fy] = gradient(rgb2gray(img));

E = abs(fx)+abs(fy);

Page 5: Image Retargeting Seam Carving

4

The next step is to calculate the cumulative minimum energy M and find out the optimal seam.

Construct a new function called vertical, which takes in the image and the number of seams need

to remove or insert as input parameters. Then most part of the image retargeting implementation

will be in this function.

Shrinking Images

First consider the case of removing seams. For each iteration, the program needs to calculate the

updated energy e of the image, and derives M from e using the algorithm in Section 2. However,

even if we have the minimum cost of the best seam, it does not necessarily mean that we have

the seam. Therefore, it is important to store whether we have chosen j – 1, j, or j + 1 when

minimizing M(i,j) from the row below. To achieve this, I implement a matrix called Seammat

that stores the decision for each M(i,j). Notice that special attention should be paid to pixels at

the edge of the image. This can be illustrated in the following code fragments. To keep the

program concise, I put it into a function named findSeamVert. Figure 3.2 shows the visualization

of M in vertical direction, in which dark areas mean low cumulative energy cost and bright areas

mean high cumulative energy cost. From the figure we can see that the optimal vertical seam

might be at the right edge of the image since that area is darkest in general.

Function findSeamVert:

for i = 1:R-1 % for pixels at the first column M(R-i,1) = M(R-i,1)+min([M(R-i+1,1),M(R-i+1,2)]); if M(R-i+1,1) < M(R-i+1,2) Seammat(R-i,1) = 0; elseif M(R-i+1,1) > M(R-i+1,2) Seammat(R-i,1) = 1; end % for pixels at the last column M(R-i,C) = M(R-i,C)+min([M(R-i+1,C-1),M(R-i+1,C)]); if M(R-i+1,C-1) < M(R-i+1,C) Seammat(R-i,C) = -1; elseif M(R-i+1,C-1) > M(R-i+1,C) Seammat(R-i,C) = 0; end % for other pixels in between for j = 2:C-1 M(R-i,j) = M(R-i,j)+min([M(R-i+1,j-1),M(R-i+1,j),M(R-i+1,j+1)]); if min([M(R-i+1,j-1),M(R-i+1,j),M(R-i+1,j+1)]) == M(R-i+1,j-1) Seammat(R-i,j) = -1; elseif min([M(R-i+1,j-1),M(R-i+1,j),M(R-i+1,j+1)]) == M(R-i+1,j) Seammat(R-i,j) = 0; elseif min([M(R-i+1,j-1),M(R-i+1,j),M(R-i+1,j+1)]) == M(R-i+1,j+1) Seammat(R-i,j) = 1; end end end

Page 6: Image Retargeting Seam Carving

5

Figure 3.2 Seam Costs of Entire Image in Vertical Direction

Given M, it is then easy to find the optimal seam. Following the algorithm mentioned in Section

2, we can find the minimal value of the top row of M and its location in the row. This location is

the first entry of the seam. Then we can trace back to find all pixels of the whole seam using

following code fragments. Figure 3.3 shows the first optimal vertical and horizontal seam found

using above algorithm. As expected, this seam is at the right/upper side of the image, which

means the above codes work properly.

Segments of function Vertical:

After finding the seam, it is necessary to remove it from the image. To achieve this, I

implemented a function called s_remove, which takes in the image, the seam, and the direction as

input parameters. The basic idea of removing seam is to create a mask in which only the pixels at

the seam are defined as false while other pixels are defined as true. Then initialize a new image

matrix of size that is one column less than the original image, and set the values of the matrix to

the corresponding pixel values of the image where mask shows true. As a result, the seam pixels

will be discarded. Also in order to implement with RGB images, the function called repmat is

used to duplicate the mask to three layers. However, due to the inside algorithm of MATLAB,

repmat can only be applied to horizontal seam removal, while for vertical seams, manual

implementation is needed, which can be shown as the following codes. Repeating the above

procedures shrinks the image to the desired sizes.

seamcost = min(M(1,:)); % find the minimum of cumulative energy seamloc = find(M(1,:)==seamcost); seam(1) = seamloc(1); % locate the entry of first pixel of best seam for l = 2:R seam(l) = seam(l-1)+Seammat(l-1,seam(l-1)); % search for the best seam end

Page 7: Image Retargeting Seam Carving

6

Function s_remove:

Figure 3.3 Example of Vertical and Horizontal Optimal Seams

Stretching Images

Stretching image needs some more efforts because simply duplicating the best seams will result

in the same seam being copied multiple times, making the image visually unpleasant, as Figure

3.4 shows.

function newimg = s_remove(img,S,alpha) % this function removes a seam from the image

sz = size(img); if alpha == 1 % vertical seam remove mask = true(sz(1:2)); % create a mask of true values mask(sub2ind(sz(1:2),1:sz(1),S)) = false; % set the seam pixels to

false newimg = zeros(sz-[0 1 0]); % initialize new image tempmask = mask'; for j = 1:3 temprgb = newimg(:,:,j)'; imgrgb = img(:,:,j)'; temprgb(:) = imgrgb(tempmask); newimg(:,:,j) = temprgb'; end elseif alpha == 0 % horizontal seam remove mask = true(sz(1:2)); mask(sub2ind(sz(1:2),S,1:sz(2))) = false; mask = repmat(mask,[1 1 3]); % replicate the mask to RGB layers newimg = zeros(sz-[1 0 0]); newimg(:) = img(mask); end

Page 8: Image Retargeting Seam Carving

7

Figure 3.4 Same Seam Found and Inserted Multiple Times [1]

The general solution to this problem is to find all the seams to be removed first, and then

duplicate them all together. For the coding part, it takes some effort to find the exact location of

each seam in the original image, since all seam locations found are relative to the corresponding

image that have been shrunk. To keep track of the locations of seams, I create a vector named

seamvec to store the absolute location of each seam that has already been removed, and sort it in

ascending order. For each newly found seam, if there are m seams to the left of it, we just need to

add m to its relative location to get the absolute location. For implementation, assume the length

of sorted seamvec is p, then subtract vector [1:p] from this sorted vector, and calculate the

number of entries that is smaller than the newly found seam location. Adding this number back

to the seam location will give us the real location of the seam in the original image. This can be

illustrated in the following code fragments, in which matrix seamnew is the real seam matrix.

Segments of function Vertical:

After getting the absolute locations of seams, we need to duplicate these seams to expand the

image. For inserting seams, I implement a function called s_insert, which takes in the image, the

seam, and the direction as input parameters. My implementation of inserting seams is a little

different from removing seams. Here I need to create a new image matrix which is one column

larger than the original image, and set values before and at the seam to the corresponding pixel

values of the original image. For pixels after the seam, just make them equal to the pixels that are

one column before them.

seamsort = sort(seamvec); % sort the removed seams in ascending order p = length(seamsort); if p == 0 num(k) = 0; elseif p > 0 seamtemp = seamsort-(1:p); num(k) = sum(seamtemp < seam(k,1)); % check how many seams before the

current seam are reomved end seamnew(k,:) = seam(k,:)+num(k); % get the real location of current seam seamvec = [seamvec seamnew(k,1)]; % store it in seamvec

Page 9: Image Retargeting Seam Carving

8

Function s_insert:

To successfully duplicate the seams for my algorithm, it is important to start inserting seams

from right to left. Therefore, before calling the s_insert function, we need to sort the seams in

descending order as the following code fragments show.

Object Removal/Protection

One important application of seam carving is object removal/protection. The basic idea is to

choose a region that needs to be removed, and assign pixels in this region with very high

negative/positive costs. To implement the idea in MATLAB, I included an argument

weightsmask to the ImageRetarget function. weightsmask is a matrix the size of the original

image that allows user to specify large negative or large positive weights for parts of the image

function newimg = s_insert(img,S,alpha)

% this function removes a seam from the image

sz = size(img);

if alpha == 1 % insert vertical seam

newimg = zeros(sz+[0 1 0]);

for k = 1:sz(1)

for l = 1:S(k)

newimg(k,l,:) = img(k,l,:);

end

for l = S(k)+1:sz(2)+1

newimg(k,l,:) = img(k,l-1,:);

end

end

elseif alpha == 0 % insert horizontal seam

newimg = zeros(sz+[1 0 0]);

for k = 1:sz(2)

for l = 1:S(k)

newimg(l,k,:) = img(l,k,:);

end

for l = S(k)+1:sz(1)+1

newimg(l,k,:) = img(l-1,k,:);

end

end

end

seam_h = seamnew(:,1); seam_s = sort(seam_h,'descend'); % sort all seams in descending order by

their first element for k = 1:abs(delta) % this loop just gets back the whole seams in the

order above sl = find(seam_h == seam_s(k)); seam_n(k,:) = seamnew(sl,:); end

Page 10: Image Retargeting Seam Carving

9

that is desired to eliminate or preserve during seam carving. It will replace the image gradient in

all locations for which weightsmask is not equal to zero.

One important thing to notice is that as the image changes sizes during seam carving,

weightsmask also need to change sizes by deleting/inserting the same seam from/into the mask.

To this point, I implemented a function mask_resize to resize the weightsmask.

Function mask_resize (for shrink):

Function mask_resize (for stretch):

4. Results

All the results in this project are computed automatically, and for some images, the results are

quite satisfactory. Seam carving works fine on images that don’t have complex structures.

However, when interesting objects span the entire image, or when the image gets too small, seam

carving still deforms important image comtents [4].

e_weight = e.*(weightsmask == 0) + weightsmask; % cover mask on the

gradient M = e_weight; % matrix of cumulative energy M

[mr,mc] = size(weightsmask);

masktemp_v = zeros(mr,mc-1); for k = 1:mr if S(k) == 1 masktemp_v(k,:) = weightsmask(k,2:end); elseif S(k) == mc masktemp_v(k,:) = weightsmask(k,1:end-1); elseif S(k) > 1 && S(k) < mc masktemp_v(k,:) = [weightsmask(k,1:S(k)-1),weightsmask(k,S(k)

+1:end)]; end end mask_new = masktemp_v;

masktemp_v2 = zeros(mr,mc+1); for k = 1:mr masktemp_v2(k,:) = [weightsmask(k,1:S(k)),weightsmask(k,S(k):end)]; end mask_new = masktemp_v2;

Page 11: Image Retargeting Seam Carving

10

Success

Original Image

Shrink Stretch

Original Image

Page 12: Image Retargeting Seam Carving

11

Shrink Stretch

Original Image

Shrink Stretch

Page 13: Image Retargeting Seam Carving

12

Original Image

Shrink Stretch

Page 14: Image Retargeting Seam Carving

13

Original Image

Shrink Stretch

Original Image

Page 15: Image Retargeting Seam Carving

14

Weight Mask

Shrink (without mask)

Shrink (with mask)

Failure

Original Image

Page 16: Image Retargeting Seam Carving

15

Shrink Stretch

Original Image

Page 17: Image Retargeting Seam Carving

16

Shrink Stretch

5. Discussion

As a conclusion, seam carving is a content-aware image editing method that can resize images

without distorting the major content of images. However, it also has certain limits. It works very

well on certain kinds of images with less complex structures, while performs poorly on images

with structures that span the entire image. Therefore, for the latter kind of images, a weighted

mask is necessary to protect the important structures.

However, above algorithm might not be optimal. Since I simply remove or insert horizontal

seams first and then vertical seams, the removal or insertion of previous horizontal seams may

affect the cost of later vertical seams and vice versa. Therefore, this raises the question of what is

the correct order of seam carving. Horizontal first? Or alternate between the two? To explore this

question, Avidan and Shamir (2007) proposed an algorithm to search for the optimal order by

using dynamic programming. The basic idea of this algorithm is to set a matrix T of size (r + 1) ×

(c + 1), where r and c are numbers of rows and columns of original image. T(i,j) means the

lowest possible cost to remove i horizontal seams and j vertical seams from the image.

Therefore, T(0,0) = 0, and our objective is to find T(r,c) which is the last entry of this matrix.

Also three other matrices of the same size of T, namely X, Y, and I are created. X(i,j) tells the

lowest cost to remove a horizontal seam from source image of dimension (r – i) × (c – j), and

similarly Y(i,j) tells the lowest cost to remove a vertical seam from source image of dimension (r

– i) × (c – j). I is used to trace back the optimal sequence of operation, i.e. if I(r,c) = 1, then

Page 18: Image Retargeting Seam Carving

17

previous optimal operation is vertical one, and if I(r,c) = 0, then previous optimal operation is

horizontal one. Then we can use the following dynamic programming to find out T(r,c).

1) 0,0 0T

2) , min 1, 1, , , 1 , 1T r c T r c X r c T r c Y r c

By this dynamic programming, we store a simple matrix I which indicates the sequence of the

two options of operation, vertical or horizontal. We can backtrack from T(r,c) to T(0,0) and

apply corresponding removal operations to the image [1].

References

[1] S. Avidan, A. Shamir, Seam Carving for Content-Aware Image Resizing, ACM SIGGRAPH,

2007.

[2] Wikipedia, Seam Carving, http://en.wikipedia.org/wiki/Seam_carving.

[3] R. David, Seam Carving Implementation, 2007.

[4] D. Simakov, Y. Caspi, E. Shechtman, M. Irani, Summarizing Visual Data Bidirectional

Similarity, CVPR, 2008.