[MATLAB] Détection de cercles

a marqué ce sujet comme résolu.

Bonjour,

J’avais déjà posté une question il y a quelques mois pour de l’analyse de cercle (voir ici). Mon code fonctionne depuis lors et le voici ci-dessous. Ce qu’il fait est de calculer le volume total de sphères contenu avec l’intérieur d’un grand cercle via une procédure expliquée par mes schémas en dessous.

En gros, on détecte le gros cercle, on l’élimine et on calcule le volume total (en détectant chaque petit cercle). Tout ça avec MATLAB et ImageJ (la première partie du code fait appel à ImageJ).

Ce que j’aimerais faire: j’aimerais pouvoir récupérer le diamètre du gros cercle que je détecte. Je ne vois pas comment implémenter cela dans mon code existant. Avez-vous une idée?

Merci !

Process:

Procédure - Etape 1
Procédure - Etape 1
Procédure - Etape 2
Procédure - Etape 2

Code:

close all
clear all
clc

% file:///Applications/MATLAB_R2018b.app/java/jar/
%% commands to start ij and mij
javaaddpath '/Applications/MATLAB_R2018b.app/java/jar/ij.jar'   
javaaddpath '/Applications/MATLAB_R2018b.app/java/jar/mij.jar'
MIJ.start('/Applications/Fiji.app/plugins/'); %Hough transform plugin
%C:/Users/avillois/Downloads/fiji-win64/Fiji.app/plugins
%%

IJ=ij.IJ(); 

%% find water-in-oil droplets with ImageJ macro that uses Hough transform
macro_path=... 
'/Users/NameofTheUser/Documents/imageJ_macro/Macro_waterinoil.ijm'; 

vol_tot_droplets=zeros(1,16);

index=0;
nloop=11;  %position (1 to 16)
npic=300;  %number of pictures,  1 to 300
res=cell(nloop,npic); 

for loop=11:nloop  
    loop_index=loop;
    for pic=1:npic
        index=index+1;
        pic_index=pic-1;
        if pic_index<10
        str=('abc');
        newStr = strrep(str,'abc',strcat('00',num2str(pic_index)));
        elseif pic_index<100
            newStr = strrep(str,'abc',strcat('0',num2str(pic_index)));
            elseif pic_index<1000
                newStr = strrep(str,'abc',num2str(pic_index));
        end
    %Path to the pictures     
    im = mijread(strcat('/Users/NameOfTheUser/Desktop/33c_20umDhh1_initial_crop_loop',num2str(loop_index),'_100Hz_150usexp_100%lamp/1_001/ImgA000',newStr,'.tif'));
    IJ.runMacroFile(java.lang.String(macro_path)); 
    res_Hough=0;  
   [size1,size2]=size(res_Hough);
   timecode = cputime;
while size2~=9;  %the program moves on after some time if it does not find droplets
    
       res_Hough=MIJ.getResultsTable();
       [size1,size2]=size(res_Hough);
       res{loop,pic}=MIJ.getResultsTable();
       e = cputime-timecode
       if e>60
           size2=9;
       end
end
  
prova=MIJ.getLog()
prova=string(prova);
    prova_old=prova;
           
    im_res=MIJ.getCurrentImage();
    
    MIJ.run('Clear Results');
    MIJ.run('Close All');
 

figure(1)
imshow(im_res,[0 255])

    [size1_Hough,size2_Hough]=size(res_Hough);
    mask=zeros(544,512);

    for i=1:size1_Hough
        k=res_Hough(i,2); %x and y are opposite in the picture and in the matrix. Equation to consider: (x-h)^2+(y-k)^2=r^2
        h=res_Hough(i,3);
        r=res_Hough(i,4);
    
    %enter the circle
    
        for x=32:544  
            for y=1:512
                if (x-h)^2+(y-k)^2<(r-16)^2
           if im_res(x,y)~=0
                mask(x,y)=255;
           end
                end
            end
        end
        %figure(index)
        %imshow(mask);
      
        [centers,radii] = imfindcircles(mask,[1 12], ...
            'ObjectPolarity','dark','Sensitivity',0.95);
        viscircles(centers,radii);
        n_droplets=length(centers);
        for d=1:length(radii)   %d: number of rows in results table from imageJ
             vol_tot_droplets(loop)=4./3*pi*radii(d)^3+vol_tot_droplets(loop);
        end
        mask=zeros(544,512);  %puts the mask back to zero, before proceeding to the next water in oil droplets
    end
        
        res_Hough=0;
        im_res=0;
     
    end  %end for cicle related to 300 pictures
end
+0 -0

En fait je ne suis pas sûr je dois faire la différence ou simplement si ma variable 'r' (ligne 75) est déjà le rayon de la grande. Et donc il me suffirait d’incruster ligne 76: vol_ow = 4/3pir^3; non?

Car sinon je ne vois pas quelle différence et comment l’écrire.

Merci!

Heu attends, pourquoi tu écris r=res_Hough(i,4); et tu t’en sers après si tu ne sais pas ce que c’est ? C’est du code que tu as copié sans réfléchir ? Sans vouloir te faire la morale, c’est pas une bonne idée pour progresser. En tout cas, vu le Equation to consider: (x-h)^2+(y-k)^2=r^2 qui ressemble furieusement à une équation de cercle et la comparaison ensuite, r est le rayon d’un cercle. Lequel par contre, je dois t’avouer que le code que tu présentes est assez cryptique… Si tu sais que ce bout de code traite ce grand cercle, il y a des chances pour que ce r soit effectivement son rayon. Mais ça, c’est un peu ton boulot de le vérifier, c’est quelque chose d’important quand on réutilise un code.

Merci ! Oui, ce code est rempli de copier-coller d’autres morceaux de code mais il semble fonctionner correctement. rr est bien le rayon du gros cercle extérieur et j’ai mis "-16" (arbitrairement car j’ai vu que ça fonctionnait bien) pour avoir le cercle intérieur.

Ce que je ne sais pas c’est comment écrire ça. Je pensais écrire ligne 76 (dans le for): vol_ow = 4/3pir^3

Puis, ligne 98 (avant le mask): normalized_vol(loop)=vol_tot_droplets(loop)/vol_ow;

En gros, je veux calculer le volume total de petites sphères et diviser ça par le volume de la grande correspondante.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte