matlab - How to segment binary image based on concavity? -
i have binary image such as:
i looking separate main big elliptical white section little mushroom cloud on top. needs automatic process many different images, may quite different still have characteristic of main blob , touching smaller blob either above or sides.
i thinking of using watershed doesn't work in cases depending on proportions of blob. trying see if there way of finding edge of binary image , putting condition on concavity of edge cannot find how this.
ideally implementation in matlab if can done better in scipy/mathematica, that's fine well.
here's attempt. code rough, it's general idea of how can use boundary , signed curvature find 2 points segment "mushroom top" rest of body, , using turn predicate determine points of interest.
clear; clc; binary_img = imread('bin.jpg') > 100; % boundaries b = bwboundaries(binary_img); % largest boundary b = b{cellfun(@length,b) == max(cellfun(@length,b))}; % filter boundary - use circular convolution b(:,1) = cconv(b(:,1),fspecial('gaussian',[1 81],40)',size(b,1)); b(:,2) = cconv(b(:,2),fspecial('gaussian',[1 81],40)',size(b,1)); % find curvature curv_vec = zeros(length(b),1); = 0:size(b,1)-1 p_b = b(mod(i-25,length(b))+1,:); % p_b = point before p_m = b(mod(i,length(b))+1,:); % p_m = point middle p_a = b(mod(i+25,length(b))+1,:); % p_a = point after dx_ds = p_a(1)-p_m(1); % first derivative dy_ds = p_a(2)-p_m(2); % first derivative ddx_ds = p_a(1)-2*p_m(1)+p_b(1); % second derivative ddy_ds = p_a(2)-2*p_m(2)+p_b(2); % second derivative curv_vec(i+1) = dx_ds*ddy_ds-dy_ds*ddx_ds; end % find local maxima curvature [pks,locs] = findpeaks(curv_vec); [pks,pks_idx] = sort(pks); % select 2 largest curvatures p1_max = b(curv_vec == pks(end),:); p2_max = b(curv_vec == pks(end-1),:); % paint biggest contiguous region rp = regionprops(binary_img,'area','pixelidxlist','pixellist'); rp = rp(max(vertcat(rp.area)) == vertcat(rp.area)); % paint points left of line img = zeros(size(binary_img)); img(rp.pixelidxlist) = 0.5; = 1:length(rp.pixellist) turn = sign(det([1 p1_max(1) p1_max(2); 1 p2_max(1) p2_max(2); 1 rp.pixellist(i,2) rp.pixellist(i,1);])); if (turn > 0) img(rp.pixellist(i,2),rp.pixellist(i,1)) = 1; end end figure(1); subplot(1,3,1); plot(b(:,1), b(:,2),'o'); hold on; plot(p1_max(1), p1_max(2),'ro','markersize',5,'linewidth', 5); plot(p2_max(1), p2_max(2),'ro','markersize',5,'linewidth', 5); subplot(1,3,2); plot(curv_vec); subplot(1,3,3); imshow(img);
using image:
output:
Comments
Post a Comment