How to resize a specific part of an image?

19 views (last 30 days)
Hello,
Does anyone know how I can resize a specific object in an image while the other dimensions are the same? Imagine we have a small circle inside of a big circle; how can I increase the size of the bigger circle while the smaller is constant, or how can I decrease the size of the smaller circle while the bigger circle is constant?
Thanks.
Here, I have created an example by magic select in paint 3D.

Accepted Answer

DGM
DGM on 2 Apr 2022
Edited: DGM on 3 Apr 2022
It would help if the image weren't mutilated by compression to begin with, and it depends what the requirements actually are. I think the ideal solution would simply be to reconstruct the objects as a set of polygons and then reconstruct a fresh raster image with the desired object geometry.
That said, I'm going to go somewhere in-between full vector reconstruction and direct image filtering. In this example, the image is reduced to a set of non-binarized masks so as to preserve any antialiasing. These masks are then transformed independently to a new geometry and then a composition-based approach is used to construct a new color image from the masks.
The latter part of this example uses tools from MIMT. This is not strictly necessary, but it is a convenience that I'm not in the mood to avoid today. I started by cleaning up one half of the supplied image (attached).
inpict = imread('star.png');
inpict = rgb2gray(inpict);
% these are the original colors
bgcolor = [148 149 153];
starcolor = [36 30 30];
hexcolor = [209 210 212];
% extract hexagon
hexmask = imdilate(inpict>180,ones(5));
hex = imadjust(inpict,stretchlim(inpict,0.1));
hex = hex.*uint8(hexmask);
% extract star
star = (255-inpict)-106;
star = imadjust(star,stretchlim(star,0.1));
star = star + uint8(hexmask)*255;
% configuration for rescaling objects
starscale = 0.8;
hexscale = 1.5;
staroffset = [10 0];
hexoffset = [10 0];
% create transformation matrix, transform star
sz = size(star);
starxfm = diag([starscale starscale 1]);
starxfm(3,1:2) = staroffset*starscale;
starxfm = affine2d(starxfm);
outview = affineOutputView(sz(1:2),starxfm,'boundsstyle','centeroutput');
star = imwarp(star,starxfm,'outputview',outview);
% create transformation matrix, transform hex
hexxfm = diag([hexscale hexscale 1]);
hexxfm(3,1:2) = hexoffset*hexscale;
hexxfm = affine2d(hexxfm);
outview = affineOutputView(sz(1:2),hexxfm,'boundsstyle','centeroutput');
hex = imwarp(hex,hexxfm,'outputview',outview);
% create flat RGB images for each object
starpict = colorpict([sz(1:2) 3],starcolor,'uint8');
hexpict = colorpict([sz(1:2) 3],hexcolor,'uint8');
background = colorpict([sz(1:2) 3],bgcolor,'uint8');
% compose images using star,hex as alpha
outpict = replacepixels(starpict,background,star);
outpict = replacepixels(hexpict,outpict,hex);
imshow(outpict)
These are results for differing values of starscale and hexscale:
The last example also demonstrates the use of independent offsets.
Since this image is constructed from scratch, the colors don't have to be the same as in the original image:
Similarly, the object stacking order doesn't have to be the same either:
I should point out that it's not strictly necessary to create flat images for the object overlays prior to composition. MIMT replacepixels() can also just accept the color tuple directly:
% create flat RGB image for the background only
background = colorpict([sz(1:2) 3],bgcolor,'uint8');
% compose images using star,hex as alpha
outpict = replacepixels(starcolor/255,background,star);
outpict = replacepixels(hexcolor/255,outpict,hex);
  3 Comments
Ryan Parvar
Ryan Parvar on 4 Apr 2022
thanks for your great code, still it doesn't work when I run it and there is an error in line :
starpict = colorpict([sz(1:2) 3],starcolor,'uint8');
....
DGM
DGM on 4 Apr 2022
Both these examples use tools from MIMT (on the File Exchange). Both colorpict() and replacepixels() are from MIMT.
As mentioned, this composition can be done without those tools, but avoiding them is just tedium.
For example, this line:
background = colorpict([sz(1:2) 3],bgcolor,'uint8');
can be replaced with this:
background = repmat(permute(uint8(bgcolor),[1 3 2],sz(1:2));
These lines:
outpict = replacepixels(starpict,background,star);
outpict = replacepixels(hexpict,outpict,hex);
can be replaced with this fragile mess:
star = im2double(star);
hex = im2double(hex);
outpict = im2double(starpict).*star + im2double(background).*(1-star);
outpict = im2double(hexpict).*hex + outpict.*(1-hex);
outpict = im2uint8(outpict);
... assuming I didn't make any mistakes.

Sign in to comment.

More Answers (2)

Matt J
Matt J on 1 Apr 2022
One way would be to perform an erosion using bwlerode (downloadable from here)
load Image
B=bwlerode(A,3,strel('disk',8));
tiledlayout(1,2)
nexttile; imshow(A/max(A(:)),[])
nexttile; imshow(B/max(B(:)),[])
  2 Comments
DGM
DGM on 2 Apr 2022
Edited: DGM on 2 Apr 2022
I think you missed some files when you updated. The only thing in the archive is linexlines2D().
Matt J
Matt J on 2 Apr 2022
Strange. Anyway, I've fixed it now.

Sign in to comment.


yanqi liu
yanqi liu on 2 Apr 2022
yes,sir,may be make the target thin,such as
im = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/949514/image.jpeg');
im2 = imcrop(im, [3 3 199 199]);
bw = im2bw(im2);
bw2 = ~imfill(~bw, 'holes');
sz = size(bw);
bw3 = bwselect(bw, round(sz(2)/2), round(sz(1)/2));
% bwmorph
bw3 = bwmorph(bw3, 'thin', 5);
bw2(bw3) = 1;
figure; montage({mat2gray(bw),mat2gray(bw2)}, 'Size', [1 2], 'BackgroundColor', 'r', 'BorderSize', [2 2]);

Community Treasure Hunt

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

Start Hunting!