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.

 채택된 답변

DGM
DGM 2022년 4월 2일
편집: DGM 2022년 4월 3일

1 개 추천

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);

댓글 수: 5

DGM
DGM 2022년 4월 3일
편집: DGM 2022년 4월 3일
For a hard-edged vector reconstruction of the primitives, consider the alternative example. This still uses MIMT tools. The image is reduced to binary masks which are analyzed to find the radii and centroids of the two objects. From this, ROI tools are used to create new binary masks with the specified scale and offset. From the new masks, an image is constructed by basic composition as in the above example.
inpict = imread('star.png');
inpict = rgb2gray(inpict);
sz = size(inpict);
% these are the original colors
bgcolor = [148 149 153];
starcolor = [36 30 30];
hexcolor = [209 210 212];
% extract objects as binary masks
star = imfill(inpict<50,'holes');
hex = inpict>180;
% find object center and radii
% note that i'm not looking for rotation angle
% i choose to assume that the polygons are ostensibly
% oriented such that one apex is directly at 90deg
S = regionprops(star,'centroid');
cs = S.Centroid;
[spy spx] = find(bwperim(star));
spr = sqrt(sum(([spx spy]-cs).^2,2));
rsmin = min(spr);
rsmaj = max(spr);
S = regionprops(hex,'centroid');
ch = S.Centroid;
[hpy hpx] = find(bwperim(hex));
hpr = sqrt(sum(([hpx hpy]-ch).^2,2));
rhmaj = max(hpr);
% configuration for rescaling objects
starscale = 1.5;
hexscale = 0.8;
staroffset = [0 0];
hexoffset = [0 0];
% use ROI tools to create new polygonal masks
th = 90 + 360/10*(0:9);
r = repmat([rsmin rsmaj]*starscale,[1 5]);
[x y] = pol2cart(th.'/180*pi,r.');
imshow(star) % just a placeholder to fill the axes
Rs = images.roi.Polygon(gca);
Rs.Position = [x y]+cs+staroffset;
starmask = createMask(Rs);
th = 90 + 360/6*(0:5);
r = repmat(rhmaj*hexscale,[1 6]);
[x y] = pol2cart(th.'/180*pi,r.');
Rh = images.roi.Polygon(gca);
Rh.Position = [x y]+ch+hexoffset;
hexmask = createMask(Rh);
% compose new image
background = colorpict([sz(1:2) 3],bgcolor,'uint8');
outpict = replacepixels(starcolor/255,background,starmask);
outpict = replacepixels(hexcolor/255,outpict,hexmask);
imshow(outpict)
It's worth noting that this assumes that the polygons are regular. In the original image, the star is not regular. Similarly, this ignores any slight rotation the objects might have.
Ryan Parvar
Ryan Parvar 2022년 4월 4일
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');
....
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.
WANG
WANG 2025년 3월 25일
Is there a way to maintain the size of the image after implementation?
DGM
DGM 2025년 3월 25일
I don't understand. In both of the examples, the output image (outpict) has the same geometry (204x204) as the input image (inpict), regardless of the scale and offset parameters.

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

추가 답변 (2개)

Matt J
Matt J 2022년 4월 1일
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

DGM
DGM 2022년 4월 2일
편집: DGM 2022년 4월 2일
I think you missed some files when you updated. The only thing in the archive is linexlines2D().
Matt J
Matt J 2022년 4월 2일
Strange. Anyway, I've fixed it now.

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

yanqi liu
yanqi liu 2022년 4월 2일
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]);

카테고리

도움말 센터File Exchange에서 Convert Image Type에 대해 자세히 알아보기

질문:

2022년 4월 1일

댓글:

DGM
2025년 3월 25일

Community Treasure Hunt

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

Start Hunting!

Translated by