How to resize a specific part of an image?

17 vues (au cours des 30 derniers jours)
Ryan Parvar
Ryan Parvar le 1 Avr 2022
Commenté : DGM le 4 Avr 2022
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?
Here, I have created an example by magic select in paint 3D.

Réponse acceptée

DGM le 2 Avr 2022
Modifié(e) : DGM le 3 Avr 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);
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 commentaires
DGM le 4 Avr 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.

Connectez-vous pour commenter.

Plus de réponses (2)

Matt J
Matt J le 1 Avr 2022
One way would be to perform an erosion using bwlerode (downloadable from here)
load Image
nexttile; imshow(A/max(A(:)),[])
nexttile; imshow(B/max(B(:)),[])
  2 commentaires
Matt J
Matt J le 2 Avr 2022
Strange. Anyway, I've fixed it now.

Connectez-vous pour commenter.

yanqi liu
yanqi liu le 2 Avr 2022
yes,sir,may be make the target thin,such as
im = imread('');
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]);


En savoir plus sur Image Processing Toolbox dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by