How to resize a specific part of an image?

19 visualizaciones (últimos 30 días)
Ryan Parvar
Ryan Parvar el 1 de Abr. de 2022
Comentada: DGM el 4 de Abr. de 2022
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.

Respuesta aceptada

DGM
DGM el 2 de Abr. de 2022
Editada: DGM el 3 de Abr. de 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 comentarios
Ryan Parvar
Ryan Parvar el 4 de Abr. de 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 el 4 de Abr. de 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.

Iniciar sesión para comentar.

Más respuestas (2)

Matt J
Matt J el 1 de Abr. de 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 comentarios
DGM
DGM el 2 de Abr. de 2022
Editada: DGM el 2 de Abr. de 2022
I think you missed some files when you updated. The only thing in the archive is linexlines2D().
Matt J
Matt J el 2 de Abr. de 2022
Strange. Anyway, I've fixed it now.

Iniciar sesión para comentar.


yanqi liu
yanqi liu el 2 de Abr. de 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]);

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by