No BSD License  

Highlights from
Simple Particle Tracking

from Simple Particle Tracking by Martin Pastor
Detection of bright spots into a sequence of images and track its trajectory

detect_spot_gray_original(s_raiz,umbral_1,umbral_2,area_1,area_2,caja,elipse)
function detect_spot_gray_original(s_raiz,umbral_1,umbral_2,area_1,area_2,caja,elipse)

% Este programa busca los centroides en la escala de grises de los puntos 
% brillantes en una imagen. Esta hecho de tal manera que puede buscar los 
% centroides de una secuencia de imagenes.

% s_raiz: nombre base del archivo (cuidado, 'nombre_base')
% umbral_1: minimo en la escala de grises
% umbral_2: mximo en la escala de grises
% area_1: rea mnima
% area_2= rea mxima (para no ejecutar el criterio de reas, area_1 y area_2 ambos cero)
% caja= proporcin entre anchura y altura de los spots (para no hacer cero)
% elipse= excentricidad (para no hacer 1).


close all
set(0,'defaulttextinterpreter','none');

dir_0='C:\programas\';           % origen del programa
dir_1='C:\origen_imagenes\';     %origen de la imagenes
dir_2='C:\guardar_datos\';       % carpeta donde se guardan los datos

formato='.tif';         % formato de imagen
n_number=6;             % numero de dgitos que diferencian cada imagen
refresco=100;           % numero de imagen que hago antes de parar.
pausar=5;               % tiempo a parar el ventilador.
num=8;                  % primeros y segundos vecinos.

    %% busqueda de spots

files=dir(strcat(dir_1,'*',formato));
nfiles=length(files);   % numero de imagenes en la carpeta
image_cali=imread(strcat(dir_1,files(1).name));
tam_image=size(image_cali);
n_rows=tam_image(1);             % numero de filas y columnas de las imagenes
n_columns=tam_image(2);
clear files image_cali tam_image;

data=[];

disp(s_raiz);

for n=1:nfiles,
    
    n_zeros=n_number-length(num2str(n));    %se elige el numero de ceros del nombre
    cero='0';
    while (length(cero)<n_zeros),
        cero=strcat(cero,'0');
    end
    s=strcat(s_raiz,cero,num2str(n),formato);
    
    A=imread(strcat(dir_1,s));A=A(:,:,1);                            % se lee el archivo de imagen
    
    % se binariza de acuerdo a dos umbrales
    
    I=zeros(size(A));              
    cambiar=find(([A]>=umbral_1)&([A]<=umbral_2));
    I(cambiar)=1;
    I=imfill(I,'holes');        % relleno huecos
    
    [labeled,numObjects] = bwlabel(I,num);    % busquedad de cluster: etiquetado y propiedades
    balldata = regionprops(labeled,'Area');
    
    % criterio de areas
    
    if ((area_1~=0) | (area_2~=0))  % si se elige criterio de area se ejecuta este paso
        
        selected = find(([balldata.Area]>=area_1)&([balldata.Area]<=area_2));   % eleccion de cluster de acuerdo al area
        I = ismember(labeled,selected);
        
    end

    [labeled,numObjects] = bwlabel(I,num);    % busquedad de cluster: etiquetado y propiedades
    balldata = regionprops(labeled,'Eccentricity');
        

    % criterio de excentricidad

    if (elipse~=1)  % si se elige criterio de area se ejecuta este paso

        selected = find([balldata.Eccentricity]<=elipse);   % eleccion de cluster de acuerdo a la excentricidad
        I = ismember(labeled,selected);

    end

    [labeled,numObjects] = bwlabel(I,num);    % busquedad de cluster: etiquetado y propiedades
    balldata = regionprops(labeled,'Centroid','Area','BoundingBox','Eccentricity');
      
    
    if (~isempty(balldata))     % sin hay algn punto

        %centroides
        
        for k=1:numObjects,     % calcular centroide con la escala de grises
            
            clear grays row column;
            [row,column]=find(labeled==k);                  % coordenadas de la region seleccionada
            grays=double(A((column-1)*n_rows+row));   % nivel de gris de las coordenadas de la region selecionada

            x_gray(k)=column'*grays/sum(grays);
            y_gray(k)=row'*grays/sum(grays);
            
        end
        
        clear grays row column;

        centroids= [balldata.Centroid];
        if (~isempty(centroids))
            x=centroids(1:2:end-1);
            y=centroids(2:2:end);
        end

        % area

        area=[balldata.Area];

        % rectangulo

        BB= [balldata.BoundingBox];
        if (~isempty(BB))
            x_BB=BB(1:4:end-3);
            y_BB=BB(2:4:end-2);
            ancho_BB=BB(3:4:end-1);
            alto_BB=BB(4:4:end);
        end

        % excentricidad

        excentricidad=[balldata.Eccentricity];

        data_act=[n*ones(length(balldata),1) x_gray' y_gray' area' x_BB' y_BB' ancho_BB' alto_BB' excentricidad' x' y'];
        clear x_gray y_gray;

        % criterio de rectangulo

        if (caja~=0)  % si se elige criterio de area se ejecuta este paso

            selected = find(((ancho_BB./alto_BB)>=caja)|((alto_BB./ancho_BB)>=caja));   % eleccion de cluster de acuerdo al area
            if (~isempty(selected))            % el formato de datos es x e y en una misma columna
                data_act(selected,:)=[];
            end

        end
        
    else
        
        data_act=[];
        
    end % si hay puntos
    
    if (~isempty(data_act))
        data=[data;data_act]; %guardar datos
    end

    if (mod(n,refresco)==0)
        disp(n);
        imshow(A);
        hold on;
        if(~isempty(data_act))
            plot(data_act(:,2),data_act(:,3),'or','MarkerSize',2)
        end
        hold off;
        title(strcat('Image: ',s));
        pause(pausar);
    end
        
    clear x y area x_BB y_BB ancho_BB alto_BB ex;
    clear data_act data_g_act;
    
end

param=[num umbral_1 umbral_2 area_1 area_2 caja elipse n_rows n_columns];


save(strcat(dir_2,s_raiz,'_param.dat'),'param','-ASCII');
save(strcat(dir_2,s_raiz,'_fxyA.dat'),'data','-ASCII');


cd(dir_0);

Contact us at files@mathworks.com