## how to find dent in a circle?

on 8 May 2013

### Image Analyst (view profile)

how to find dent in a circle?

## Products

### Image Analyst (view profile)

on 8 May 2013

Not exactly sure what you mean by "find" - for example is it just a binary image of the dent alone, or is it an array of all the (row, column) pairs of pixels that comprise the dent. But anyway, you can just get a binary image of the bojects and then use bwconvhull

```dentsImage = bwconvhull(binaryImage) - binaryImage; % Get image.
[rows columns] = find(dentsImage); % Get (y,x) coordinates.
```

Image Analyst

### Image Analyst (view profile)

on 8 May 2013

You can get the convex hull from regionprops.

Otherwise, here's a demo, for what it's worth:

```% Demo to show a use case for the overall convex hull of a group/cluster/collection of binary blobs,
% as well as a demo of two different ways to do the convex hull of the group (mine and Steve's),
% and a way to do convex hull of individual blobs rather than the whole collection of them.
function convexhulldemo()
% Clean up.
clc;
clear all;
close all;
workspace;
```
```% Open up an image -- the standard MATLAB demo image of the coins.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
filename = fullfile(folder, 'coins.png'); % Standard demo image.
subplot(3, 3, 1);
imshow(originalImage, []);
title('Original Image');
set(gcf, 'units','normalized','outerposition',[0 0 1 1]); % Maximize figure.
```
```% Threshold the image.
binaryImage = originalImage > 100;
subplot(3, 3, 2);
imshow(binaryImage, []);
title('Thresholded Image');
```
```% Take the convex hull of all 10 coins.
[convexHullImage hullVerticesX hullVerticesY] = imConvexHull(binaryImage);
subplot(3, 3, 3);
imshow(convexHullImage, []);
title('Convex Hull of All 10 Coins');
```
```% Show original image with convex hull outline plotted over it.
subplot(3, 3, 4);
imshow(originalImage, []);
hold on;
plot(hullVerticesX, hullVerticesY, 'r');
title('Convex Hull Outline of All 10 Coins');
```
```% Calculate the Euclidean Distance Map.
edmImage = bwdist(binaryImage);
subplot(3, 3, 5);
imshow(edmImage, []);
title('Original EDM Image - note high values in corners');
```
```% Mask it by the convex hull.
edmImage2 = edmImage .* single(convexHullImage);
maxDistance = max(max(edmImage2));
edmImageNorm = edmImage2 / maxDistance;
subplot(3, 3, 6);
imshow(edmImage2, []);
```
```% Get the histogram of the masked EDM Image.
[counts gls] = imhist(edmImageNorm, 40);
maxY = max(counts(2:end));
subplot(3, 3, 7);
bar(gls, counts);
ylim([0 maxY * 1.05]);
xlim([0 1]);
```
```% Skeletonize it so that we get just the ridgelines of the EDM.
skeletonImage = edmImage2>0;
skeletonImage2 = bwmorph(skeletonImage, 'skel', inf);
subplot(3, 3, 8);
imshow(skeletonImage2, []);
title('Skeleton of the Masked EDM Image');
```
```% Multiply the masked EDM by the skeleton so we have ONLY ridgeline pixels.
ridgeImage = (edmImage2 .* single(skeletonImage2)) / maxDistance;
[counts gls] = imhist(ridgeImage, 40);
maxY = max(counts(2:end));
subplot(3, 3, 9);
bar(gls, counts);
ylim([0 maxY * 1.05]);
xlim([0 1]);
title('Histogram of only the Ridgelines of the Masked EDM Image');
```
```%-------------------------------------------------------------
% Now let's try Steve Eddins's function.
hFig2 = figure; % Open up new, separate figure window.
set(gcf, 'Position', 0.75 * get(0, 'ScreenSize')); % Maximize figure.
CenterFigure(hFig2);
```
```% Open up an image.
subplot(2, 3, 1);
imshow(originalImage, []);
title('Original Image');
```
```% Cut some notches in the coins so we can see the effect of individual convex hulls.
notchedCoinsImage = originalImage;
notchedCoinsImage(40:60, 40:82) = 65;
notchedCoinsImage(20:40, 130:180) = 65;
notchedCoinsImage(60:80, 200:250) = 65;
notchedCoinsImage(140:160, 80:130) = 65;
notchedCoinsImage(110:130, 160:210) = 65;
notchedCoinsImage(60:90, 100:120) = 65;
notchedCoinsImage(140:180, 230:240) = 65;
notchedCoinsImage(100:140, 30:40) = 65;
notchedCoinsImage(100:140, 30:40) = 65;
notchedCoinsImage(200:220, 80:140) = 65;
subplot(2, 3, 2);
imshow(notchedCoinsImage, []);
title('Notched Coins Image');
```
```% Threshold the image.
binaryImage2 = notchedCoinsImage > 100;
subplot(2, 3, 3);
imshow(binaryImage2, []);
title('Thresholded Image');
```
```% Take the convex hull using Steve's function (returns CH of all 10 coins.)
convexHullImage = bwconvhull(binaryImage2);
subplot(2, 3, 5);
imshow(convexHullImage, []);
title('Convex Hull of All 10 Coins');
```
```% Label the image.
labeledImage = bwconncomp(binaryImage2);
% Call regionprops
blobMeasurements = regionprops(labeledImage, 'all');
numberOfBlobs = length(blobMeasurements);
[rows columns] = size(binaryImage2);
```
```% Get convex hull of each blob in the image independently.
% It would sure be nice if this were easier.
% The "ConvexImage" returned by regionprops doesn't return full size images, just subimages.
% So if we want the convex hull of each blob independently, we have to loop over all blobs
% getting the CH for each blob one at a time, then adding it to the cumulative CH image.
CHofEachBlob = false(rows, columns);
for blob = 1 : numberOfBlobs
CHofThisBlob = [blobMeasurements(blob).ConvexHull];
CHImageForThisBlob = poly2mask(CHofThisBlob(:,1), CHofThisBlob(:,2), rows, columns);
CHofEachBlob = CHofEachBlob | CHImageForThisBlob;
end
subplot(2, 3, 6);
imshow(CHofEachBlob, []);
title('Convex Hull of each coin independently');
```
```return;  % End of the main convexhulldemo() routine.
```
```%-------------------------------------------------------------------------------------
% Mark Hayworth's version to get the convex hull of the entire group of blobs.
function [convexHullImage hullVerticesX hullVerticesY] = imConvexHull(binaryImage)
[rows columns] = size(binaryImage);
boundaries = bwboundaries(binaryImage);
numberOfBlobs = size(boundaries, 1);
blobVertices = [];
for k = 1 : numberOfBlobs
thisBoundary = boundaries{k};
blobVertices = [blobVertices; thisBoundary];
hold on;
plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 2);
end
hullIndexes = convhull(blobVertices(:,2), blobVertices(:,1));
hullVerticesX = blobVertices(hullIndexes,2);
hullVerticesY = blobVertices(hullIndexes,1);
convexHullImage = poly2mask(hullVerticesX, hullVerticesY, rows, columns);
return;

%-------------------------------------------------------------------------------------
% Steven L. Eddins's version to get the convex hull of the entire group of blobs.
function out = bwconvhull(in)
%BWCONVHULL Convex hull of binary image
%   bw2 = bwconvhull(bw) computes the convex hull of the input binary image, bw,
%   and returns it as another binary image, bw2.  bw2 has the same size as bw.
%
%   bw must be two-dimensional.
```
```%   Steven L. Eddins
%   Copyright 2009 The MathWorks, Inc.
```
```if ~islogical(in)
in = in ~= 0;
end
```
```% Convert input from logical to uint8.  This will cause regionprops to treat
% it as a label matrix, and so every foreground pixel will be treated as part of
% the same object.
in = uint8(in);
```
```s = regionprops(in, 'BoundingBox', 'ConvexImage');
```
```% regionprops returns an image only big enough to just cover the bounding box of
% the "object."  Compute the row and column indices corresponding to that
% bounding box.
m = s.BoundingBox(4);
n = s.BoundingBox(3);
r1 = s.BoundingBox(2) + 0.5;
c1 = s.BoundingBox(1) + 0.5;
r = (1:m) + r1 - 1;
c = (1:n) + c1 - 1;
```
```out = false(size(in));
out(r,c) = s.ConvexImage;
```
```%-------------------------------------------------------------------------------------
% Function to center a figure on the screen (if it's not maximized).
function CenterFigure(handleToFigure)
% The figure Position property
% does not include the window borders, so this example uses a width of 5 pixels
% on the sides and bottom and 30 pixels on the top.
borderWidth = 5;
titleBarWidth = 30;
% Ensure root units are pixels and get the size of the screen:
set(0, 'Units', 'pixels');
set(handleToFigure, 'Units', 'pixels');
% Get the screen size in pixels.
screenSize = get(0,'ScreenSize');
% Get the size of the window.
initialFigurePosition = get(handleToFigure, 'Position');
% Create an array that will center it.
centeredX = (screenSize(3) - initialFigurePosition(3)) / 2;
centeredY = (screenSize(4) - initialFigurePosition(4)) / 2;
centeredPosition  = [centeredX,...
centeredY,...
initialFigurePosition(3),...
initialFigurePosition(4)];
set(handleToFigure, 'Position', centeredPosition);
return; % from CenterFigure()

```
Sivakumaran Chandrasekaran

### Sivakumaran Chandrasekaran (view profile)

on 9 May 2013

Thank you so much image analyst. I am getting error in s.BoundingBox(4);Field reference for multiple structure elements that is followed by more reference blocks is an error.What does it indicates. is there any problem in the input image which i gave.

Image Analyst

### Image Analyst (view profile)

on 9 May 2013

I just ran it again and it works fine. What error did you get? You probably modified it so that it doesn't work.