views:

303

answers:

1

This is a further question based on this answer:

http://stackoverflow.com/questions/2589851/how-can-i-implement-this-visual-effect-in-matlab/2589957#2589957

The general solution should work for all background colors and length/width ratios.

+1  A: 

As is often the case, there are a number of different ways to do this in MATLAB. I'll list a few examples for padding RGB images...

Solution #1: Add padding with CAT to make a square image

This solution takes a given color padColor and replicates it using the function REPMAT to create padding of the right size, shape, and color. The padding is then added to the sides of the image using the function CAT:

[r,c,d] = size(rgbImage);  %# Get the image dimensions
nPad = abs(c-r)/2;         %# The padding size
padColor = [1 1 1];        %# RGB triple for pad color (white)
padColor = reshape(padColor,1,1,3);  %# Reshape pad color to 1-by-1-by-3
if c > r                   %# Pad rows
  newImage = cat(1,repmat(padColor,floor(nPad),c),...  %# Top padding
                   rgbImage,...                        %# Image
                   repmat(padColor,ceil(nPad),c));     %# Bottom padding
elseif r > c               %# Pad columns
  newImage = cat(2,repmat(padColor,r,floor(nPad)),...  %# Left padding
                   rgbImage,...                        %# Image
                   repmat(padColor,r,ceil(nPad)));     %# Right padding
end

You can modify the above solution to work for indexed, grayscale, or binary images by replacing the two lines defining the padColor with one of the following:

padColor = uint8(1);    %# For an indexed image (index of color to use)
padColor = uint8(255);  %# For a grayscale image (white)
padColor = true;        %# For a binary image (white)


Solution #2: Make a blank square image and insert the original image

This solution takes a given color padColor and replicates it using the function REPMAT to create a blank square image of that color. The original image is then inserted into this blank image in a centered position:

[r,c,d] = size(rgbImage);  %# Get the image dimensions
padColor = [1 1 1];        %# RGB triple for pad color (white)
padColor = reshape(padColor,1,1,3);  %# Reshape pad color to 1-by-1-by-3
if c > r                   %# Pad rows
  newImage = repmat(padColor,c);  %# Make c-by-c-by-3 matrix of given color
  rowIndex = floor((c-r)/2);      %# Row index for inserting image
  newImage(rowIndex+(1:r),:,:) = rgbImage;     %# Insert the image
elseif r > c               %# Pad columns
  newImage = repmat(padColor,r);  %# Make r-by-r-by-3 matrix of given color
  columnIndex = floor((r-c)/2);   %# Column index for inserting image
  newImage(:,columnIndex+(1:c),:) = rgbImage;  %# Insert the image
end

You can modify the above solution to work for indexed, grayscale, or binary images by replacing the two lines defining the padColor with one of the following:

padColor = uint8(1);    %# For an indexed image (index of color to use)
padColor = uint8(255);  %# For a grayscale image (white)
padColor = true;        %# For a binary image (white)


Solution #3: Use PADARRAY

This solution uses the function PADARRAY to create the padding to make the image square. Unfortunately, there's no easy way to specify the padding color you want for RGB images when using this solution (see below). However, you can use the 'replicate' argument to have PADARRAY simply replicate the color at the edges of the image where it is adding the padding:

[r,c,d] = size(rgbImage);  %# Get the image dimensions
nPad = abs(c-r)/2;         %# The padding size
if c > r                   %# Pad rows
  newImage = padarray(rgbImage,[floor(nPad) 0],...  %# Pad top
                      'replicate','pre');
  newImage = padarray(newImage,[ceil(nPad) 0],...   %# Pad bottom
                      'replicate','post');
elseif r > c               %# Pad columns
  newImage = padarray(rgbImage,[0 floor(nPad)],...  %# Pad left
                      'replicate','pre');
  newImage = padarray(newImage,[0 ceil(nPad)],...   %# Pad right
                      'replicate','post');
end

This solution will work for indexed, grayscale, or binary images. For these three image types, you have the option to replace the 'replicate' argument with a scalar value that you want to use for the padding (i.e. uint8(255) for white padding in a grayscale image). For RGB images, replacing the 'replicate' argument with a single value will only allow you to create padding colors that are gray shades ranging from white to black (i.e. 1 creates white padding).

gnovice
How does `reshape` work here?
@user198729: The function RESHAPE changes the size of a matrix or vector. I change `padColor` from a 1-by-3 matrix into a 1-by-1-by-3 matrix because that makes it easier to later expand it to an N-by-M-by-3 padding matrix using REPMAT.
gnovice
Seems there is no logic to retrieve the background color for padding,so I assume it's hardcoded and this won't work for all background colors?
@user198729: I added a few more options for you to choose from. You can easily add logic yourself to choose what you deem the "background color" to be. For example, you could choose the top left corner color of the image to be the background color by saying `padColor = rgbImage(1,1,:);`. Alternatively, the third solution I list above will simply replicate the edge colors of the image to color the padded areas.
gnovice
Thanks in advance,seems quite a lot for me to digest,I'll accept this as soon as I understand it:)
What does `...` mean in `cat(2,repmat(padColor,r,floor(nPad)),...` ?
@user198729: The `...` is the line continuation operator (http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_env/f0-5789.html#f0-5857), which allows you to write a multiple-line statement in cases where just one line would be very long. It generally improves the format and readability of the code by avoiding the need to scroll left and right to read everything.
gnovice
@gnovice, sorry to peppering about this question,I tried to assign `padColor` another value:`padColor=1.2;padColor = reshape(meanColor,1,1,3);` but got a error:`To RESHAPE the number of elements must not change.`,how to do it the proper way?
@user198729: You have to replace *both* lines with your new line defining `padColor` as a scalar value. So, just get rid of the line that does the reshaping since it isn't necessary when `padColor` isn't an RGB triple.
gnovice