# defining the center of an image and recognise the contrast disks

6 views (last 30 days)

Show older comments

sesilia maidelin
on 10 Feb 2022

Commented: sesilia maidelin
on 17 Feb 2022

##### 2 Comments

Simon Chan
on 10 Feb 2022

Edited: Simon Chan
on 10 Feb 2022

### Accepted Answer

DGM
on 10 Feb 2022

Edited: DGM
on 10 Feb 2022

Consider the example:

A = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/890405/image.png');

B = bwareafilt(A<128,3); % pick the 3 objects with largest area

imshow(B)

% get properties

S = regionprops(B,'area','solidity','centroid','minferetproperties','boundingbox');

C = vertcat(S.Centroid);

ara = vertcat(S.Area);

sol = vertcat(S.Solidity);

mind = vertcat(S.MinFeretDiameter);

% try to discern which objects are which

[~,isring] = max((mind.*ara)./sol);

[~,isbox] = max(sol./ara);

% get relevant geometry information

Bring = S(isring).BoundingBox;

Cring = Bring(1:2) + Bring(3:4)/2; % center of ring

Cbox = C(isbox,:); % center of box

Rring = mind(isring)/2; % approx radius of ring

boxloc = (Cbox-Cring).*[1 1]; % relative position vector of box

baserot = atan2d(boxloc(2),boxloc(1)); % base rotation of entire object

% these are constants extracted from a modified copy

% radii are relative to Rring

Rbox = 0.666*Rring;

Rdot = 0.786*Rring;

rdot = 0.0541*Rring;

dotrot = 30;

% find dot locations

dotangles = linspace(dotrot,180-dotrot,9) + [0; 180] + baserot;

dotangles = flipud(reshape(dotangles.',[],1));

[dotx doty] = pol2cart(dotangles*pi/180,Rdot);

dotxy = [dotx doty] + Cring;

imshow(A); hold on

plot(dotxy(:,1),dotxy(:,2),'o')

%% try to get samples by doing a local average around each point

dotsamples = zeros(numel(dotx),1);

sc = size(A);

[xx yy] = meshgrid(1:sc(2),1:sc(1));

for k = 1:numel(dotx)

mask = ((xx-dotxy(k,1)).^2+(yy-dotxy(k,2)).^2) <= (rdot*0.5)^2;

samplesize = nnz(mask);

dotsamples(k) = sum(A(mask))/samplesize;

end

dotsamples

This should work even if the object is rotated or moved/scaled. The thresholding might need to be adjusted if the contrast and levels change.

##### 7 Comments

DGM
on 16 Feb 2022

Edited: DGM
on 16 Feb 2022

Regarding the question you asked about how the locations are determined:

Once a new image is thresholded, there are only two objects of interest -- the dark ring near the perimeter, and the dark off-center square. The location of the phantom is represented by the center of the ring. The rotation of the phantom is determined by the location of the square with respect to the ring center.

Once the center and base rotation angle are known, the angular displacement of the dots is known. The angle between the square and the first dot is 30d. The angle between each dot is 15d. The radial position of the dots is known relative to the ring radius, so the ring radius will resolve that.

In short, the only information that's needed from the incoming image are the ring center and radius, and the square's location.

Of course, one might ask where those precalculated constants came from. I started by editing a copy of the original image to make it easier to segment.

% extract geometry constants from simplified copy

A = imread('diskxrt.png');

B = bwareafilt(A<128,3);

imshow(B)

S = regionprops(B,'area','solidity','centroid','minferetproperties','boundingbox');

C = vertcat(S.Centroid);

ara = vertcat(S.Area);

sol = vertcat(S.Solidity);

mind = vertcat(S.MinFeretDiameter);

[~,isring] = max((mind.*ara)./sol);

[~,isdot] = max(sol./ara);

isbox = 3;

Bring = S(isring).BoundingBox;

Cring = Bring(1:2) + Bring(3:4)/2; % ring center calculated as center of bbox

%Cring = C(isring,:); % ring center as calculated from image centroid

Cbox = C(isbox,:);

Rring = mind(isring)/2;

boxloc = (Cbox-Cring).*[1 -1];

baserot = atan2d(boxloc(2),boxloc(1));

% these are relative to Rring (as calc via Cring/Bring)

Rbox = norm(Cbox-Cring)/Rring % 0.6474 0.6661

Rdot = norm(C(isdot,:)-Cring)/Rring % 0.7670 0.7853

rdot = S(isdot).MinFeretDiameter/2/Rring % 0.0541 0.0541

dotloc = (C(isdot,:)-Cring).*[1 -1];

dotrot = atan2d(dotloc(2),dotloc(1)) - baserot % 30.285 29.499

dotangles = linspace(dotrot,180-dotrot,9) + [0; 180]

hold on;

plot(C(isring,1),C(isring,2),'yo')

plot(C(isdot,1),C(isdot,2),'*')

plot(C(isbox,1),C(isbox,2),'s')

### More Answers (0)

### See Also

### Community Treasure Hunt

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

Start Hunting!