How do I add a black border around an image?

조회 수: 160 (최근 30일)
Jonathan Carey
Jonathan Carey 2020년 9월 23일
편집: DGM 2022년 7월 16일
Trying to add a simple black border to an image.

답변 (3개)

Rik
Rik 2020년 9월 23일
You can pad an array with zeros.
IM=uint8(255*rand(100,100));
IM2=zeros(120,120,'like',IM);
IM2(11:110,11:110)=IM;
imshow(IM2)
%or directly with the image processing toolbox:
IM3 = padarray(IM,[10 10],0,'both');
  댓글 수: 3
Rik
Rik 2021년 2월 23일
Putting in a color is actually easier to do with the first solution, as the B = padarray(A,padsize,padval) syntax only allows you to specify a scalar. Just create the IM2 variable with your required color. Alternatively you can loop over the three dimensions and use the padval syntax.
DGM
DGM 2022년 7월 12일
@Francisco J. Rodríguez's comment-as-answer moved here:
I have always needed this tool and to do this task I always have to add lines and lines of code. This command works perfectly, even on images with many layers, such as RGB or spectral images. THANK YOU.

댓글을 달려면 로그인하십시오.


DGM
DGM 2021년 11월 6일
편집: DGM 2022년 7월 16일
Rik already gave the non-IPT and IPT methods. I'm just going to add a bunch of examples for a more generalized reference covering black/gray/white borders, along with colored and textured borders.
Say you have an RGB image:
% RGB test image
A = imresize(imread('peppers.png'),0.5);
Using IPT padarray():
For black, white, or grayscale padding of uniform width, padarray is convenient enough. This will work regardless of whether the image is RGB or grayscale.
% using IPT padarray() to create a uniform black border
B = padarray(A,[10 10],0,'both');
But often it's desired for the pad widths to be nonuniform. This example is extreme for sake of clarity, but small nonuniformity is often required (e.g.) when the difference between the original and output geometry is not integer-divisible by 2. Doing this with padarray() is a bit inconvenient.
% using IPT padarray() to create a nonuniform black border
C = padarray(A,[5 7],0,'pre');
C = padarray(C,[15 13],0,'post');
This alone is a minor inconvenience, but If you want a colored border on a color image, you'll have to jump through some hoops.
% using IPT padarray() to create a uniform colored border
% scale of padcolor must be matched to image class
% size of padcolor must be matched to image depth
padcolor = [255 50 128];
for c = 1:size(A,3)
D(:,:,c) = padarray(A(:,:,c),[10 10],padcolor(c),'both');
end
Obviously, trying to make this nonuniform gets one step worse. If you want to add colored borders on a mix of color and grayscale images, that's just another hoop to jump through.
Composition by direct indexing:
A border can also be added by creating an underlying matting image and then inserting your original image into it using basic array indexing. This isn't very verbose, but it's also not very readable, and it's hardly convenient. Again, you'll have to make sure that the matting image matches the original image in both depth and class.
% use image insertion to create a nonuniform black border
% depth/class of matting must match image
padsize = [5 15 7 13]; % [top bottom left right]
[h w ch ~] = size(A);
E = zeros(h+sum(padsize(1:2)),w+sum(padsize(3:4)),ch,class(A));
E(padsize(1)+1:padsize(1)+h,padsize(3)+1:padsize(3)+w,:) = A;
Similar can be done to create colored padding. As with the last padarray() example, adding a colored padding to an image which might be color or grayscale would require extra conditional checks and preprocessing.
% use image insertion to create a colored border
% depth/class of matting must match image
% note that there isn't a convenient way to scale the color tuple to match the image
% since im2uint8(), im2double(), etc all have the parameter of interest embedded in the function name
padcolor = uint8([255 50 128]); % SCALE, DEPTH AND CLASS IS SET HERE
padsize = [5 15 7 13]; % [top bottom left right]
[h w ch ~] = size(A);
F = repmat(permute(padcolor,[1 3 2]),[h+sum(padsize(1:2)) w+sum(padsize(3:4))]);
F(padsize(1)+1:padsize(1)+h,padsize(3)+1:padsize(3)+w,:) = A;
Since these are basic image composition techniques, this could also be used to create a patterned or textured border using an appropriately-textured image for matting.
Using third-party tools:
That's some of the basic ways to do it. There are tools in MIMT (on the File Exchange) which can simplify the task and help make it less sensitive to the tedious details of class/depth.
Single-color borders:
MIMT has addborder() which is made for adding matting to images. It's not as general-purpose as padarray(), but for images, it's often more convenient.
% using MIMT addborder() to create a uniform black border
D = addborder(A,10);
% using MIMT addborder() to create a nonuniform black border
E = addborder(A,[5 15 7 13]);
% using MIMT addborder() to create an asymmetric color border
I = addborder(A,[10 15],[255 50 128]);
Addborder will automatically expand the image, so adding a colored border to a grayscale image requires no additional consideration.
% add a colored border to a single-channel image
G = addborder(rgb2gray(A),10,[255 50 128]);
Addborder() also supports RGBA and IA color specification, though nothing outside of MIMT knows what to do with a 2 or 4 channel image.
% add a semitransparent border to an RGB image
H = addborder(A,10,[255 50 128 128]);
While these examples show the color tuple specified in the same class as the original image, addborder() can accept unit-scale tuples regardless of input class.
Patterned/textured borders:
What if you want a border that's something other than a single color? What if you want a patterned or textured border of some sort? Recall the basic example using image insertion by array indexing. That would be one way. Using MIMT tools, one might do something like this:
% use replacepixels to create a patterned/textured border
% add uniform-width transparent border to image
FG = addborder(A,10,[0 0]);
szo = imsize(FG,2);
% use a texture image from a file and make it fit the same geometry
%BG = imresize(imread('sources/crumpledpaper.jpg'),szo); % RGB, uint8
% use a modified copy of the FG
BG = imbcg(imgaussfilt(imresize(A,szo),5),'b',-0.5,'gimpmode'); % RGB, uint8
% compose output
L = replacepixels(FG,BG,1); % class and depth are automatically handled
The source image doesn't have to be a photograph. If you're already using MIMT, there are plenty of ways to generate the matting image.
% use replacepixels to create an asymmetric patterned/textured border
% add asymmetric-width transparent border to image
FG = addborder(A,[10 15],[0 0]);
szo = imsize(FG,2);
% or generate the underlying image instead
% find an ugly tileable pattern/texture from somewhere
%BG = ptile(imread('sources/patterns/ospat/OldSchool_A6_151.png'),szo); % grayscale, uint8
%BG = ptile(imread('sources/patterns/gpat/ground1.png'),szo); % RGB, uint8
% generate colored clouds
%BG = perlin([szo 3]); % RGB, 'double'
% generate a linear gradient
BG = lingrad([szo 3],[0 0; 1 1],[128 50 255; 255 50 128],'linear','linrgb'); % RGB, uint8
% compose output
M = replacepixels(FG,BG,1); % class and depth are automatically handled
... though you may wish to pay more regard to taste than I have. Note that in both these examples, no attention needs to be paid to matching the class and depth of the two images.
Synthesis:
As with anything, you can make it as complicated as you want by combining various methods.
% combine multiple things
% add uniform-width gradient border
FG = addborder(A,1,[0 0]);
szo = imsize(FG,2);
BG = lingrad([szo 3],[0 0; 1 1],[128 50 255; 255 50 128]*0.7,'linear','linrgb'); % RGB, uint8
FG = replacepixels(FG,BG,1);
% add asymmetric-width border using a blurred and darkened copy
FG = addborder(FG,[8 14],[0 0]);
szo = imsize(FG,2);
BG = imbcg(imgaussfilt(imresize(A,szo),5),'b',-0.5,'gimpmode'); % RGB, uint8
FG = replacepixels(FG,BG,1);
% add uniform-width gradient border
FG = addborder(FG,1,[0 0]);
szo = imsize(FG,2);
BG = lingrad([szo 3],[0 0; 1 1],[128 50 255; 255 50 128],'linear','linrgb'); % RGB, uint8
FG = replacepixels(FG,BG,1);
% add outer matting
N = addborder(FG); % default pad width is proportional to image diagonal
If the images being composited are all centered, this could also be done using imstacker(). It's not necessarily more compact or memory efficient, but sometimes it's easier to think through and read. Considering that much of MIMT is designed around ad-hoc image editing, the subjective aspects of convenience aren't to be ignored.
% do the same thing using imstacker instead
% create all frames
szo = imsize(A,2)+2;
BG1 = lingrad([szo 3],[0 0; 1 1],[128 50 255; 255 50 128]*0.7,'linear','linrgb'); % RGB, uint8
szo = szo+[8 14]*2;
BG2 = imbcg(imgaussfilt(imresize(A,szo),5),'b',-0.5,'gimpmode'); % RGB, uint8
szo = szo+2;
BG3 = lingrad([szo 3],[0 0; 1 1],[128 50 255; 255 50 128],'linear','linrgb'); % RGB, uint8
szo = szo + round(norm(szo)*0.030);
BG4 = zeros(szo); % grayscale, 'double'
% pad with alpha, center, stack on dim4
P = imstacker({A BG1 BG2 BG3 BG4}); % defaults work fine here
% compose all frames, strip extraneous alpha
P = splitalpha(mergedown(P,1,'normal'));
Hopefully that's helpful to someone.

yanqi liu
yanqi liu 2021년 11월 8일
편집: yanqi liu 2021년 11월 8일
clc; clear all; close all;
im = imread('cameraman.tif');
im2 = padarray(im,[20 20],'both');
figure; imshow(im)
figure; imshow(im2)
clc; clear all;
im = imread('cameraman.tif');
th = 20;
sz = size(im);
if length(sz) == 2
sz(3) = 1;
end
im2 = zeros(2*th+sz(1),2*th+sz(2),sz(3));
im2(th:th+sz(1)-1,th:th+sz(2)-1,:) = im;
im2 = uint8(im2);
figure; imshow(im,[])
figure; imshow(im2,[])
  댓글 수: 4
Rik
Rik 2021년 11월 8일
I would suggest avoiding clc;clear all;close all; as a habit. Especially clear all is not necessary.
yanqi liu
yanqi liu 2021년 11월 8일
yes,sir,its great idea

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

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

Start Hunting!

Translated by