top of page

QA0004

QA0004 notes:

Small tag OK.jpg
Q: How to measure centre and radius of the central circle with single click.
A:
 

clear all;clc;close all

A=imread('001.jpg');
figure(1);imshow(A);                                            
% only use 1 RGB layer

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

A1=A(:,:,1);

A2=imbinarize(A1); 

scale_factor=1;
A2=imresize(A2,scale_factor);
figure(2);imshow(A2)

hold all

display('single click on any pixel inside circle')
p1=ginput(1)
nx1=p1(1);ny1=p1(2);

display('//n')
display(['x1= ' num2str(p1(2)) ' ,  y1= ' num2str(p1(1))])
plot(p1(1),p1(2),'r*')

%%
% draw 1st cross

kx=nx1
ky=ny1
kx_right=nx1
kx_left=nx1
ky_up=ny1
ky_down=ny1

while A2(ky_up,kx)==0    ky_up=ky_up-1;plot(kx,ky_up,'g*');  end;
while A2(ky_down,kx)==0    ky_down=ky_down+1;plot(kx,ky_down,'g*');  end;
while A2(ky,kx_right)==0    kx_right=kx_right+1;plot(kx_right,ky,'g*');  end;
while A2(ky,kx_left)==0    kx_left=kx_left-1;plot(kx_left,ky,'g*');  end;

kx_range=[kx_left:1:kx_right];
ky_range=[ky_up:1:ky_down];

log_ky_up=0                                                         % shift horizontal, above
for k=1:1:numel(kx_range)
    ky_up=ny1;
    while A2(ky_up,kx_range(k))==0    
        ky_up=ky_up-1; %  plot(kx_range(k),ky_up,'g*');  
        log_ky_up=[log_ky_up ky_up];
    end;
end
log_ky_up(1)=[];

log_ky_down=0                                                     % shift horizontal, below
for k=1:1:numel(kx_range)
    ky_down=ny1;
    while A2(ky_down,kx_range(k))==0    
        ky_down=ky_down+1;  %  plot(kx_range(k),ky_down,'b*');  
        log_ky_down=[log_ky_down ky_down];
    end;
end
log_ky_down(1)=[];


ky_up=ny1;                                                          % shift vertical, left
log_kx_left=0
for k=1:1:numel(ky_range)
    kx_left=nx1;
    while A2(ky_range(k),kx_left)==0  
        kx_left=kx_left-1; %  plot(kx_left,ky_range(k),'r*');  
        log_kx_left=[log_kx_left kx_left];
    end;
end
log_kx_left(1)=[];

log_kx_right=0                                                      % shift vertical, right
for k=1:1:numel(ky_range)
    kx_right=nx1;
    while A2(ky_range(k),kx_right)==0    
        kx_right=kx_right+1;  %  plot(kx_right,ky_range(k),'y*');  
        log_kx_right=[log_kx_right kx_right];
    end;
end

log_kx_right(1)=[];

R01=.5*abs(min(log_ky_up)-max(log_ky_down))
R02=.5*abs(min(log_kx_left)-max(log_kx_right))

 

 

 


R0=max(R01,R02)

c0x=.5*abs(min(log_kx_left)+max(log_kx_right))
c0y=.5*abs(min(log_ky_up)+max(log_ky_down))

viscircles([c0x c0y],R0,'EdgeColor',[1 0 1],'LineWidth',2.5)

R0 =    91


c0x =   137
c0y =   131

001.jpg
002.jpg

following a start script to find all radii and centres that that generate circles fitting the circle of interest. 2 problems: 1.- too slow compared to the previous script that goes straight to the solution 2.- the following lines harvest all fitting circles within range of radii supplied in advance, but it takes minutes to sweep a single radius value, throughout all points, therefore it's not a practical solution but the following lines may be helpful to solve other problems:

clear all;clc;close all

A=imread('001.jpg');
figure(1);imshow(A);                                            
% only use 1 RGB layer
A1=A(:,:,1);

A2=imbinarize(A1);                                               % reduce px range to bianry [0 1]
% figure(2);imshow(A2);                                           % Y axis horizontal, X axis vertical.

%%
% the actual image requires a lot of time for the probe cricle to sweep the entire image.
% resizing, processing, and then

scale_factor=.9
A2=imresize(A2,scale_factor)
figure(2);imshow(A2)

%%

% expected R within Rmin Rmax

[sz1 sz2]=size(A2)   % sz1 Y, sz2 X
sz1=floor(scale_factor*sz1);
sz2=floor(scale_factor*sz2);

da=2*pi/21;   % angle resolution
a=[0:da:2*pi-da];

Rmin2=floor(75*scale_factor);
Rmax2=floor(95*scale_factor);
R2=[Rmin2:1:Rmax2]

    % all points
[X0,Y0]=meshgrid([1:sz2],[1:sz1]);
P0=zeros(sz2,sz1,2);
P0(:,:,1)=X0';P0(:,:,2)=Y0';
P0=reshape(P0,numel(X0),2);
P0x=P0(:,1);P0y=P0(:,2);

% focus on minority: finding coordinates of A2 points that have value 1
nA2_1=find(A2>0);
[nyA2_1,nxA2_1]=ind2sub(size(A2),nA2_1);


hold all
% plot(nxA2_1,nyA2_1,'r*');                                  % test all 1 points fit exactly 

%%

cxlog=0
cylog=0
rlog=0

hold all

for k=1:1:numel(R2)                                             % sweep radius value 
  
    cx=[R2(k)+1:1:sz2-R2(k)-1];
    cy=[R2(k)+1:1:sz1-R2(k)-1];
      
    P=[0 0]
    for k1=cx
          for k2=cy
              P=[P;k1 k2];
          end
    end
    P(1,:)=[];
    Px=P(:,1);Py=P(:,2);

    cr0x=R2(k)*cos(a);                                           % reference circle
    cr0y=R2(k)*sin(a); 
    
    for s=1:1:(sz2-2*R2(k)-2)*(sz1-2*R2(k)-2)        
% sweep probe circle centre position
             
        crcx=cr0x+Px(s);
        crcy=cr0y+Py(s);
        
         [pin,pon]=inpolygon(nxA2_1,nyA2_1,crcx,crcy);
        
        if sum(A2(pin))==0                                        
% all px inside probe circle null value: circle fits in
            cxlog=[cxlog Px(s)];
            cylog=[cylog Py(s)];
            rlog=[rlog R2(k)];
               
            plot(crcx,crcy,'y*')                                    
% plot qualifying circle
            
        end
        
    end
    
end

For the record, imfindcircles as applied in the following lines, which is how it's applied when following the basic examples available in MATLAB help, imfindcircles doesn't work.

Rmin=[10:10:250];
Rmax=Rmin+10;

tag=zeros(1,numel(Rmin)) % marker
C={}
R={}

for k=1:1:numel(Rmin)
    [centres,radii,metric]=imfindcircles(A4,[Rmin(k) Rmax(k)],'ObjectPolarity','bright');
    C=[C centres];
    R=[R radii];
    if ~isempty(centres)
        tag(k)=1;
    end
end
tag


% centersStrong5 = centers(1:5,:);
% radiiStrong5 = radii(1:5);
% metricStrong5 = metric(1:5);

% only getting a few false circles 

viscircles(centres,radii,'EdgeColor','r')
 

catch_tilted_cells_23.png
bottom of page