![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1707451/image.png)
Adjusting Convex Hull Area
12 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
![](/matlabcentral/answers/uploaded_files/1708331/image.png)
I'm trying to use convhull to calculate the area of a shape and compare that to the number of pixels of said shape. Hypothetically, the convex hull should have a greater area but that doesn't seem to be the case. Is there some way to adjust how convhull determines area?
EDIT: To clarify, I understand that I can't change the convhull function itself. I'm instead hoping for some alternative method to look at the area of something in matlab.
1 Kommentar
Stephen23
am 31 Mai 2024
Original question by Veronica retrieved from Bing Cache:
Calculating Convex Hull Area
I'm trying to use convhull to calculate the area of a shape and compare that to the number of pixels of said shape. Hypothetically, the convex hull should have a greater area but that doesn't seem to be the case. Is there some way to adjust how convhull determines area?
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1707451/image.png)
For example, the convhull of this shape says the area is 2, but there are 5 white pixels.
Antworten (3)
Steven Lord
am 31 Mai 2024
As an extreme example, what is the convex hull of a single point at the center of a pixel? It's the point itself, with size 0. That's obviously less than the count of the number of pixels containing that point, which is 1.
It sounds like you expected the convex hull of the set of data points you posted to encompass all the corners of all the pixels that contain any of the points in the data set (so from x = 1.5 to x = 4.5 and y = 1.5 to y = 4.5.) Is that correct?
John D'Errico
am 3 Jun. 2024
Bearbeitet: John D'Errico
am 3 Jun. 2024
I fail to see the issue. No, you cannot adjust how a convex hull computes the area. A convex hull does not see pixels. It sees triangles, so convex geometric objects. And it computes the area of those geometries as directed. But a convex hull is an approximation anyway, since the area you really want to compute is probably not truly convex, and surely does not have perfectly linear edges.
If, instead, you count pixels to compute the area, you are again using an approximation, a different approximation, so a completely different measure of that area. And again, you have different issues in how that is an approximation. Are some of the pixels kind of grey, instead of black or white? Maybe a pixel is only partially inside the region?
The point is, you have two totally distinct approximations to compute the same area. Both are approximations, with various sources of error in those numbers. And as such, almost always one number will be greater than the other. That is a fundamental property of numbers. Which one will be the greater, this is hard to know. Very rarely they might even be equal. But you don't really care that much, since you know they are both approximations. As long as you understand the flaws in each of those respective approximations, and they are close to each other, does it matter?
My point is, you are focusing too deeply on a non-problem. If you look for perfection in an approximation, you will always fail.
2 Kommentare
John D'Errico
am 3 Jun. 2024
Bearbeitet: John D'Errico
am 3 Jun. 2024
Excellent. I had not seen that one. The modeling quote I always liked was this one:
“The best material model of a cat is another, or preferably the same, cat.”
― Norbert Wiener
I've seen it attributed to several sources.
Image Analyst
am 3 Jun. 2024
Try regionprops
% Make cross.
cross = false(5, 5);
cross(2:4, 3) = true;
cross(3, 2:4) = true;
% Measure area of convex hull.
props = regionprops(cross, 'ConvexArea');
crossArea = props.ConvexArea
1 Kommentar
DGM
am 3 Jun. 2024
Bearbeitet: DGM
am 3 Jun. 2024
So long as we're considering the original objectives, this doesn't provide the intended answer. The answer returned by regionprops() only considers whole pixels within the convex image. In this case, the convex image of the 5px cross is the 5px cross itself.
% the test image
cross = false(5, 5);
cross(2:4, 3) = true;
cross(3, 2:4) = true;
%% %%% use bw image tools in a discrete image space %%%
% these simply give the number of true pixels in the convex image
% at this scale, the cross _is_ convex.
% use regionprops()
A1 = regionprops(cross,'convexarea','conveximage');
imshow(A1.ConvexImage,'initialmagnification','fit')
A1.ConvexArea
% use bwconvhull()
% slightly different algo,
% but the result is exactly the same here
A2 = nnz(bwconvhull(cross))
%% %%% use general polygon tools %%%
% these can give non-integer areas
% use convhull() as in OP's example
[y x] = find(cross);
ch = convhull(x,y);
A3 = polyarea(x(ch),y(ch))
% show the polygon being computed
figure
imshow(cross,'initialmagnification','fit'); hold on
plot(x(ch),y(ch)) % the convex polygon
plot(x,y,'*'); % the points being enclosed
% do what was requested
% this can probably be simplified,
% but nobody actually needs this anymore
xyc = [x-0.5 y-0.5; x-0.5 y+0.5; % corners
x+0.5 y+0.5; x+0.5 y-0.5];
xyc = unique(xyc,'rows'); % get rid of duplicates
ch = convhull(xyc(:,1),xyc(:,2));
A4 = polyarea(xyc(ch,1),xyc(ch,2))
% show the polygon being computed
figure
imshow(cross,'initialmagnification','fit'); hold on
plot(xyc(ch,1),xyc(ch,2)) % the convex polygon
plot(xyc(:,1),xyc(:,2),'*'); % the points being enclosed
Of course, I think it's valid to question whether this particular approach produced an appropriate measure for the given grayscale cluster of pixels, or whether it's still useful to others. I figured at least the comparison should help clarify some differences for readers.
Siehe auch
Kategorien
Mehr zu Bounding Regions finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!