convex hull in 3D binary matrix
20 views (last 30 days)
Show older comments
I've looked at a few options in Matlab and can't seem to find a way to do what I want it to do. How can I use Matlab to draw a convex hull around specific cells in a 3D binary matrix?
I'm working with RGB image colors in a 256x256x256 binary matrix with the axes representing the R, G, and B color coordinates from 0 to 255. If an image has a specific color, let's call it "x,y,z", then the cell at coordinates x,y,z in the matrix is set to 1, else it's a 0. What I'm doing is adding 1's to the RGB cube, each representing colors from color samples that I want to be able to flag in RGB colorspace (specifically, they represent samples of colors that need to be deleted from a given image, leaving the rest of the colors in the image unchanged). What this results in is basically like a 3D scatterplot of points in RGB space from the samples.
However, the sample colors themselves (represented by the points) are not all I'm interested in. I also want to eliminate closely-related colors whose exact RGB coordinates may not have been represented in the color samples, but those colors are similar enough to some that WERE sampled that they should be flagged along with them. Example: suppose I sample pixel value 120,96,71 in an image. A very similar color is 126,108,75. However, suppose 126,108,75 was not sampled. I still want to be able to eliminate it because it is a very similar shade to another color I want to remove.
What I want to do is to fill in nearby cells in the RGB cube representing those related color values using a 3D convex hull grouping the sampled color values together AND filling in all cells on or within the convex hull with 1's if they have not already been set to 1. I can then use the RGB cube as a lookup table to see if a given pixel value should or should not be eliminated from a given image (if a given pixel's color coordinates fall on or within the hull in RGB colorspace, it gets eliminated, if not, it remains).
Basically what I'm asking is how to do a 3D convex hull like the bwconvhull() function (which as far as I know only works for 2D images). Also note, this is different from PLOTTING a convex hull in a 3D graph. Visualization does me no good for this. I need to use the convex hull itself as a lookup table, which means this needs to be stored as a 3D binary matrix. I am aware of functions like convhull(), convhulln(), and using the Delaunay triangulation convex hull. None of these do me any good for what I'm trying to accomplish.
2 Comments
JOMS ANTONY
on 10 Jan 2024
A range based binary thresholding will help right? ie instead of looking for a specific value like 120,96,71, you can change the logic to check if the pixel values are in the custom range like (120 to 130),(90 to 100),(70 to 80) which you are looking for, By the way I would like know what is the application use-case for this. Does there exists any scenario for computing the convex hull of large 3D matrices where this thresholding thing has to be performed first on the pixels of interest
Accepted Answer
John D'Errico
on 25 Jul 2019
Edited: John D'Errico
on 25 Jul 2019
It is easy enough to do, although I will suggest that a convex hull is often a bad idea when applied to color data. AN alpha shape is often better IMHO. You don't show any data, so I'll need to conjour some up. As it turns out, I had some garbage data hidden away. I saved a .mat file with the variable mat in it.
load mat.mat
rgbind = find(mat);
[r,g,b] = ind2sub(size(mat),rgbind);
So that extracts the elements in mat that were non-zero. We can see them here:
plot3(r,g,b,'o')
grid on
box on
We can easily enough wrap a convex hull around them. I like to use alphaShape, because this allows me to plot it trivially, as well as change the value of alpha.
S = alphaShape(rgbs,inf);
plot(S)
An alpha shape with inf alpha produces the convex hull of your data.
A sometimes problem with a convex hull however, especially when applied to color data is these gamut sets are rarely convex. It is easy enough here to change alpha. But if we stick with the convex hull...
[rall,gall,ball] = ndgrid(1:256,1:256,1:256);
rgball = [rall(:),gall(:),ball(:)];
inlist = inShape(S,rgball);
sum(inlist)
ans =
1137778
256*256*256
ans =
16777216
plot3(rall(inlist),gall(inlist),ball(inlist),'.')
grid on
box on
So out of the 16.7 million possible colors we could encode in that color cube, around 1.1 million lie inside the convex hull of the point set I provided in mat.
Given inlist, it is now easy enough to go back, and stuff them into the original matrix.
More Answers (1)
Matt J
on 25 Jul 2019
Edited: Matt J
on 25 Jul 2019
It sounds like imdilate() is all that you need. Just choose the strel to be the shape of the convex neighborhood that you want.
2 Comments
Matt J
on 25 Jul 2019
Edited: Matt J
on 25 Jul 2019
For example, if you wanted your convex neighborhood around each point to be a 5x5x3 cuboid you would do,
im_out = imdilate(cube,ones(5,5,3));
Or, if you wanted the convex neighborhood to be a sphere of radius 6, you would do,
im_out = imdilate(cube,strel('sphere',6))
See Also
Categories
Find more on Geometric Transformation and Image Registration in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!