matlab - How to segment binary image based on concavity? -


i have binary image such as:

enter image description here

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:

enter image description here

output:

enter image description here


Comments

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

StringGrid issue in Delphi XE8 firemonkey mobile app -