How can I divide a whole circle into two sectors at an angle?
조회 수: 4 (최근 30일)
이전 댓글 표시
채택된 답변
DGM
2023년 8월 1일
편집: DGM
2023년 8월 1일
If you're dealing with an image that's not necessarily binarized (as in the given example), there are some considerations. If we assume it's not strictly binarized, I choose to assume it may also not be a single-channel image.
% angles of parting lines
theta = [-15 45];
% a pseudo-binary image (antialiased, RGB)
inpict = imread('gring.png');
imshow(inpict,'border','tight')
% find the center of the object
inmask = imbinarize(im2gray(inpict));
S = regionprops(inmask,'centroid');
% generate a polygonal mask
neverts = 12; % number of exterior vertices
r = norm(size(inpict,1:2)); % image diagonal
vth = linspace(min(theta),max(theta),neverts); % generate vertices in polar
vth = [vth(1) vth];
vr = [0 r*ones(1,neverts)];
vx = vr.*cosd(vth) + S.Centroid(1); % convert to rectangular, offset
vy = -vr.*sind(vth) + S.Centroid(2); % image origin is NW, not SW
smask = poly2mask(vx,vy,size(inpict,1),size(inpict,2)); % generate mask
imshow(smask,'border','tight')
% split the image
% assuming image is not strictly binarized
% assuming background is black
A = inpict.*cast(smask,class(inpict));
B = inpict.*cast(~smask,class(inpict));
% show the results
imshow([A B],'border','tight')
On the other hand, if you're dealing with strictly logical images, you can simplify things.
% angles of parting lines
theta = [-15 45];
% a strictly binary image (single-channel, logical class)
inmask = imread('gring.png'); % reuse this for sake of example
inmask = imbinarize(im2gray(inmask));
% find the center of the object
S = regionprops(inmask,'centroid');
% generate a polygonal mask
neverts = 12; % number of exterior vertices
r = norm(size(inmask,1:2)); % image diagonal
vth = linspace(min(theta),max(theta),neverts); % generate vertices in polar
vth = [vth(1) vth];
vr = [0 r*ones(1,neverts)];
vx = vr.*cosd(vth) + S.Centroid(1); % convert to rectangular, offset
vy = -vr.*sind(vth) + S.Centroid(2); % image origin is NW, not SW
smask = poly2mask(vx,vy,size(inmask,1),size(inmask,2)); % generate mask
% split the image
% assuming image is strictly binarized and logical class
A = inmask & smask;
B = inmask & ~smask;
% show the results
imshow([A B],'border','tight')
In both cases, A is the region defined by the linear sequence of angles between the elements of theta. Bear in mind that this means theta = [-60 60] and theta = [300 60] specify complementary regions.
댓글 수: 0
추가 답변 (1개)
Daniel Bengtson
2023년 8월 1일
You could use the end points of the lines to generate a mask of that section of the image.
Xpix = 480;
Ypix = 480;
figure;
imshow(zeros(Ypix,Xpix)); %pseudo image
%lines
L1 = [240 300;240 50];
L2 = [240 400;240 400];
hold on
plot([L1(1,1) L1(1,2)],[L1(2,1) L1(2,2)]);
plot([L2(1,1) L2(1,2)],[L2(2,1) L2(2,2)]);
% use coordinates of line end points to create a mask
mask = poly2mask([L1(1,1) L1(1,2) L2(1,2) L2(1,1)],[L1(2,1) L1(2,2) L2(2,2) L2(2,1)],480,480);
imshow(mask*0.5)
Note that it would probably be prudent to extend your lines until they intersect with the edge of the image, then use that intersection location in place of the actual end point of the line when generating the polygon. It would also make sense to use any corners of the image that are included within your angle when generating the polygon (in this case the top right and bottom right corners).
So in this case, assuming you have extended L1 and L2 to intercept the border (which I did not do for this example), it would take a form like this.
mask = poly2mask([L1(1,1) L1(1,2) Xpix Xpix L2(1,2) L2(1,1)],[L1(2,1) L1(2,2) 1 Ypix L2(2,2) L2(2,1)],480,480);
댓글 수: 0
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!