how can remove the object that has the maximum distance from center of image?

if we have some objects in a binary image how can remove the object that has the maximum distance from center of image? for example if this is my image:
how can I obtain this image as result:
thanks

4 Comments

Define 'distance of an object from the centre of an image'. Do you mean distance from the centroid of the object to the centre or something else?
I want to remove the object that has maximum distance from center of image?
how can define 'distance of an object from the centre of an image'? I search it but I cant define this with bwselect command...I want do this command for 100 images that not similar to each other but my goal is it to remove the farthest image from center...I hope that I could explain this thanks
By define, I meant tell us what you mean. Is the distance of the object to the centre
  • the distance from the object centroid to the centre?
  • the distance from the furthest point of the object to the centre?
  • the distance from the closest point of the object to the centre?
  • something else?
the distance from the closest point of the object to the centre? I mean this.
remove the object that the closest point of the object to center is maximum...

Sign in to comment.

Answers (6)

how can I obtain this image as result:
I don't recommend that you use distance as a criterion. It would work, but for the object you've shown, it seems quicker and easier to use solidity,
S=regionprops(Image,'Solidity','PixelIdxList');
[~,idx]=min([S.Solidity]);
Image(S(idx).PixelIdxList)=0;
This is also shift-invariant, whereas the distance criterion is not.

9 Comments

The solidity approach should get rid of that C-shaped blob as long as that thing is always going to be more C-shaped or tortuous than the two central blobs. Can we count on that? What are these things anyway? It looks like lungs in a body in a CT image and for some reason the part of the body (skin and outer fat layer) or a partial air space got segmented along with the lungs.
Is that what's happening? sara, can you show the original gray scale image that gave rise to this binary image? This seems like it might be a case of a person saying "I need to do X" but not telling you that you they really want Z and it we only knew Z we could say "You'd be better off using approach Y than approach X like you asked for.
If you know the "bad blob" is always at the top, you can also ask regionprops for the bounding box and eliminate the blob with the highest Ytop value. There are also lots of other methods depending on what we can assume. If you had a bunch of blobs with random shapes (spots/circles, asterisks, C-shapes, cigar shapes, rings, etc.) at random locations would you still use the "farthest min distance from center of image" algorithm, or solidity algorithm? Maybe not. This could be a case where someone gives a specific image and then we/someone solves it and then comes along later and says "But your algorithm didn't work for this other image" - that happens all the time and it's because the original poster didn't give the range of images that they might expect to encounter.
Yes, true. I ran with the assumption that this is a segmentation of a thoracic CT image and that the unwanted segment is from the bed. It seems like a common thing. I assumed, as well, that the same shaped bed was used in the whole ensemble of images.
Since I couldn't be sure of that, I also provided the distance-based algorithm originally requested. As you say, that could end up being inadequate too (but that's out of our hands).
thanks Matt and Image Analyst
yes Image Analyst you are right I didnt think about all the images that are not similar to each other.... it is a CT lung image I use activecontour and imfill and imclose method and the other methods for obtain this binary image.. after that I use BlobsDemo.m for remove the blob that are not lung but when I use BlobsDemo.m with 2 largest blob 'you help me before and post this code for me' ...but sometimes right lung remove because it is smaller than the top object ... I thought that if I use distance method maybe I can remove the object that is on the top of the image.. I have a lot of images that are not similar to each other ...my code should be fast running ...my code has a good answer for some images but for some images I have a problem like this...
for this my original image is like this:
I can get true binary image with activecontour for this special exam but my code should work for the other exam...I hope that I could explaine my question...
Can you explain me how can I use regionprops for the bounding box and eliminate the blob with the highest Ytop value??? thanks a lot
Can you explain me how can I use regionprops for the bounding box and eliminate the blob with the highest Ytop value???
sara, it should be something that is easy enough for you to figure out yourself from the regionprops documentation. Especially, since I did pretty much the exact same thing for you with 'Solidity' instead of 'BoundingBox'.
What do you want to find? A mask with the outer body? Mask with the body but with "holes" where the dark lungs are? You can threshold and take the largest blob. Call imfill() if you want it filled it. It doesn't look human to me. What kind of animal is this?
thanks Matt and Image Analyst
I want a mask of lungs...just lungs but my code should be good for the other images like this:
I use activecontour and imfiil and imclose...I think MAatt is right I should post an other question :
"how can remove Ytop object from binary image? "I search this and I hope I can solve this... my code give me a good answer for a lot of images if I remove the Ytop object from this I think I have a good result...dear Image Analyst my images are different so threshold dosnt give me a good result all the time...I hope my explanaition is enough.. thanks
I still don't see from your later images how you got the first image with the table on top of the body. Did you flip it vertically?
Of course if your table is in a known location, you can just use a known mask to erase it from all images.
As far as thresholding, if the body is surrounded in a white layer like the ones you posted, you can always find a threshold that works. There are a variety of ways. For example, take the histogram and use the triangle method, which I use a lot. http://www.mathworks.com/matlabcentral/fileexchange/28047-gray-image-thresholding-using-the-triangle-method
Or take the mean horizontal profile of a band going through the middle of the image and look for the "half way up" gray level when the profile goes into the body and leaves the body:
row1 = round(rows/2-30);
row2 = round(rows/2+30);
horizontalProfile = mean(grayImage(row1:row2, :), 1);
plot(horizontalProfile, 'b-');
grid on;
Examine that profile and use find() to find the leading edge and trailing edge gray levels.
yes I fill this vertically...because 2 lung connect to each other and we don't want this.
Thanks dear Image Analyst I will try this and come back...
sara commented "it is good for ELCAP dataset"

Sign in to comment.

Using distance as the criterion,
L=bwlabel(Image);
[M,N]=size(Image);
[X,Y]=ndgrid((1:M)-M/2-.5,(1:N)-N/2-.5);
distmask=(X.^2+Y.^2).*Image;
idx=L>0;
Lmin=accumarray(L(idx),distmask(idx),[],@min);
[~,idx]=max(Lmin);
Image(L==idx)=0;

4 Comments

sara Commented:
I used this but it didn't not work and the object didn't remove... did you get result??
I use
T=double(Image);
distmask=(X.^2+Y.^2).*T;
instead of
distmask=(X.^2+Y.^2).*Image;
because I had error.. thanks
Yep, I tested both this solution and the the solidity-based one that I proposed and both worked fine.
thanks Matt
for first code I get a black screen and when I use your second code I have this error
Error using .* Integers can only be combined with integers of the same class, or scalar doubles.
and when I try to change this my result is same as my input...
can you help me why I have this error... I'm confused...
The error message would have given you the line number of the error. You should be able to use whos() or the workspace browser to inspect the variables used in that line and see which are integers, which are doubles, etc...

Sign in to comment.

sara: Try the attached code (below the image in blue). I basically threshold, do a morphological opening to break away the thin table line, then extract the biggest blob. A snippet:
% Get the binaryImage
binaryImage = grayImage > 135;
% Erode to break away the table from the body
binaryImage = imopen(binaryImage, [1;1;1]);
biggestBlob = ExtractNLargestBlobs(binaryImage, numberToExtract);
It gives the image below:
Thanks ImageAnalyst and Matt
I think if I remove the top object from my binaryImage maybe my problem solve faster.Dear Matt you said it is easy but I could not write the code for this...so I post this question...when I find the best answer I will come back to this discussion...
Dear ImageAnalyst sometimes the left lung is like a seprated shape and seems to 2 seprate object so all the time biggestblob dose not work... thanks for all of your guidance

3 Comments

Then take the two biggest shapes since you know there are supposed to be two of them. If they're connected and just one blob, then it may pick up another small spurious non-lung blob. You should be able to get rid of that by size filtering like I showed in my tutorial, or with bwareaopen().
thanks ImageAnalyst. I think I could not explain my question right.. I show this image :
...if I extract 3 biggest blob left lung damage and if I use imfiil with a big strel : the lesion connect to my lungs...I can not use actvecontour with a high eteration or something like this in perviouse steps because speed of program is important...I hope I could explain my problem ...thank you for all of your helpful guidance.
dear image analyst
if we have some objects in an image is there any way to extract 2 objects that are neaerest to each other?? for example
after that I want to have this result:
Is there any way?? thanks

Sign in to comment.

Sara, regarding your comment about finding the closest pair of blobs...
"Close" has several definitions. See Hausdorf distance. But let's just assume you want the pair that has the lowest distance between the centroids. Just get the centroids using regionprops() into two arrays centroidx and centroidy. Then calculate the distances, something like
distances = zeros(numberOfBlobs, numberOfBlobs);
for b1 = 1 : numberOfBlobs
for b2 = b1 : numberOfBlobs
distances(b1,b2) = sqrt((centroidx(b1)-centroidx(b2))^2+(centroidy(b1)-centroid(b2))^2);
end
end
Then find the min pair
[blob1, blob2] = find(distances == min(distances(:)));
Then use ismember() to extract those two blobs:
binaryImage = ismember(labeledImage, [blob1, blob2]) > 0;
or something like that. That's just off the top of my head and may need editing.
If this answers your question, can you "Accept" my answer?

3 Comments

thanks ImageAnalyst

I use this code:

    if true
     I =input('enter an image','s');
I=imread(I);
Ibw = im2bw(I);
Ibw = imfill(Ibw,'holes');
Ilabel = logical(Ibw);
stat = regionprops(Ilabel,'centroid');
imshow(I); hold on;
for x = 1: numel(stat)
    plot(stat(x).Centroid(1),stat(x).Centroid(2),'ro');
end

for b1 = 1 : numel(stat)

for b2 = b1 : numel(stat)
distances(b1,b2) = sqrt((stat(b1).Centroid(1)-stat(b2).Centroid(1))^2+(stat(b1).Centroid(2)-stat(b2).Centroid(2))^2)
   end
end

tmp = distances; tmp(tmp == 0) = Inf; % as above

[colminvals, colminrows] = min(tmp); % find min in each column

[minVal, minCol] = min(colminvals) % find overall min and its column

 [blob1, blob2] = find(distances == minVal)

binaryImage = ismember(Ilabel, [blob1, blob2]) > 0;

figure,imshow(binaryImage);

    end

but I could not get the answer...and result is like input can you help me??

'hi image analyst..... 'how can I calculate the distance of each entroid from upper border line of image so that I can remove the nearest objects(centroids)) from the above image. thanks
Get the bounding box
props = regionprops(binaryImage, 'BoundingBox');
allBB = vertcat(props.BoundingBox);
% Find just top lines alone.
topLines = allBB(:, 2); % Extract column 2.
% Find out which ones are farther away than some threshold.
keepers = topLines > someLineNumber; % Whatever you want, for example 40.
% Extract out those into a new binary image.
newBinaryImage = ismember(binaryImage, find(keepers));

Sign in to comment.

sara
sara on 26 Jan 2015
Edited: sara on 26 Jan 2015

thanks ImageAnalyst

I use this code:

    if true
     I =input('enter an image','s');
I=imread(I);
Ibw = im2bw(I);
Ibw = imfill(Ibw,'holes');
Ilabel = logical(Ibw);
stat = regionprops(Ilabel,'centroid');
imshow(I); hold on;
for x = 1: numel(stat)
    plot(stat(x).Centroid(1),stat(x).Centroid(2),'ro');
end

for b1 = 1 : numel(stat)

for b2 = b1 : numel(stat)
distances(b1,b2) = sqrt((stat(b1).Centroid(1)-stat(b2).Centroid(1))^2+(stat(b1).Centroid(2)-stat(b2).Centroid(2))^2)
   end
end

tmp = distances; tmp(tmp == 0) = Inf; % as above

[colminvals, colminrows] = min(tmp); % find min in each column

[minVal, minCol] = min(colminvals) % find overall min and its column

 [blob1, blob2] = find(distances == minVal)

binaryImage = ismember(Ilabel, [blob1, blob2]) > 0;

figure,imshow(binaryImage);

    end

but I could not get the answer...and result is like input can you help me??

1 Comment

my result like these
and our endless result is
it is like our input without any changes

Sign in to comment.

Asked:

on 17 Oct 2014

Moved:

DGM
on 12 Feb 2023

Community Treasure Hunt

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

Start Hunting!