How do I create a gradient border around an image?

I need to create a border around an image that would gradually change it's color from the image's color to white (a gradient).
Thank you.

 Risposta accettata

borderwidth = 7; %for example
[R, C, P] = size(YourImage);
augmented_col_coords = [-borderwidth+1, 1:C, C+borderwidth];
augmented_row_coords = [-borderwidth+1, 1:R, R+borderwidth];
resample_col_coords = -borderwidth+1 : C + borderwidth;
resample_row_coords = -borderwidth+1 : R + borderwidth;
extra_line = repmat(255, 1, C+2);
augmented_red = [extra_line; 255*ones(R,1), double(YourImage(:,:,1)), 255*ones(R,1); extra_line];
gradiented_red = uint8( interp2(augmented_col_coords, augmented_row_coords, augmented_red, resample_col_coords, resample_row_coords.') );
augmented_green = [extra_line; 255*ones(R,1), double(YourImage(:,:,2)), 255*ones(R,1); extra_line];
gradiented_green = uint8( interp2(augmented_col_coords, augmented_row_coords, augmented_green, resample_col_coords, resample_row_coords.') );
augmented_blue = [extra_line; 255*ones(R,1), double(YourImage(:,:,3)), 255*ones(R,1); extra_line];
gradiented_blue = uint8( interp2(augmented_col_coords, augmented_row_coords, augmented_red, resample_col_coords, resample_row_coords.') );
gradiented_image = cat(3, gradiented_red, gradiented_green, gradiented_blue);

6 Commenti

It works, but for some reason it replaces the image colors with different ones and I get an error "Index exceeds matrix dimensions." with certain images, I can't understand why. Furthermore, whould it be possible to get explanations on what each line does? Thank you!
Could you attach a couple of the images that it fails on?
The code works by putting a line of white at a distance of "borderwidth" away from the edge of the image, and then doing 2D interpolation to fill in the gap.
The reason I used 2D interpolation instead of plain 1D interpolation from the edges (which would not have been difficult to compute for most locations) was to better handle the corners. For example if the border width were 10, then the color in the upper left corner has 10 steps of size 1 to adjust to white in the left direction, and 10 steps of size 1 to adjust to white in the up direction, but for the diagonal it is 10 steps of size 1.4 so the fade should be different in the diagonal directions and the rate depends upon the angle. Easiest to let interp2 worry about it.
Well i get the "Index exceeds matrix dimensions." message when I use these images:
Plus, if I don't get the message and it works, then it changes the color values. For example: Input:
Result:
Why does it happen? And How do I fix it?
Solution attached. Invoke as
[result, cmap] = bordering(FilenameString);
result will be the resulting data array, and cmap will be the associated colormap (possibly empty.)
You can then do
imshow(result, cmap)
or
imwrite(result, cmap, NewFilenameString)
You will probably not be so pleased with the output for the snow picture, but doing better for indexed images is a bit tricky unless you are willing to convert the indexed image to RGB.
What if i only want to fix the color change problem? What changes must be made to the original code, so that the colors wouldn't get changed?
gradiented_blue = uint8( interp2(augmented_col_coords, augmented_row_coords, augmented_blue, resample_col_coords, resample_row_coords.') );

Accedi per commentare.

Più risposte (1)

DGM
DGM il 16 Lug 2022
Modificato: DGM il 16 Lug 2022
You could also do this by using inpainting tools.
Using IPT regionfill():
A = imread('peppers.png');
padwidth = [30 30];
outercolor = 255; % must be scalar (black/gray/white)
% create a mask to define the transition region
mk = false([size(A,1) size(A,2)]);
mk = padarray(mk,padwidth-1,1,'both');
mk = padarray(mk,[1 1],0,'both');
% pad the image
B = padarray(A,padwidth,outercolor,'both');
% inpaint based on the mask
for c = 1:size(B,3)
B(:,:,c) = regionfill(B(:,:,c),mk);
end
imshow(B)
Using John's inpaint_nans():
A = imread('peppers.png');
padwidth = [30 30];
outercolor = 255; % must be scalar (black/gray/white)
% pad the image, using NaNs to define the transition region
B = padarray(double(A),padwidth-1,NaN,'both');
B = padarray(B,[1 1],outercolor,'both');
% inpaint based on NaNs
for c = 1:size(B,3)
B(:,:,c) = inpaint_nans(B(:,:,c),2);
end
B = uint8(B); % cast back to uint8
imshow(B)
Note that both of these examples assume that input image is class uint8.

Categorie

Scopri di più su Read, Write, and Modify Image in Centro assistenza e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by