Image Processing

di il
27 risposte

Image Processing

Salve,

Dovrei estrarre la griglia millimetrata dall'immagine allegata (che è una sorte di calibrazione) e sovrapporla ad altre immagini.
Avevo pensato di contare il numero di pixel in un millimetro e fissare il pixel centrale dell'immagine e costruire la griglia di conseguenza, solo che non so se è il metodo migliore.
Avete consigli?
Quali istruzioni mi consentono di fissare le coordinate del pixel centrale e fare in modo che in un'immagine diversa lo stesso pixel rappresenti l'origine?
Allegati:
9724_967eac446708b53d51c8b6d28ecf7e36.jpg
9724_967eac446708b53d51c8b6d28ecf7e36.jpg

27 Risposte

  • Re: Image Processing

    Allora, se devi disegnare la griglia su delle immagini credo che la cosa migliore sia misurare, come dici tu, il numero di pixel dei quadrati della griglia e riprodurlo sulle altre immagini, a partire dal centro.
    Per misurare la grandezza del quadrato puoi usare la funzione imdistline. Ti permette di tracciare una linea tra due punti dell'immagine e ti da come risultato la distanza in pixel tra i due punti.
    A questo punto disegnare la griglia è abbastanza semplice.
    Devi considerare che il nero è rappresentato nell'immagine dai pixel con valore 0. Quindi il problema si riduce a creare delle righe di zeri sull'immagine che devi grigliare.
    Quindi prendi il centro dell'immagine, che non è altro che una matrice, quindi numero-di-righe/2 e numero-di-colonne/2, e fai un ciclo for per disegnare le righe e uno per disegnare le colonne (il ciclo for probabilmente neanche serve).
  • Re: Image Processing

    Allora ho fatto scritto quattro righe:

    cal = imread ('percorso immagine.jpg');
    imshow(cal)
    impixelinfo;
    h=imdistline;
    dist = getDistance(h);

    Mi mostra l'immagine e fa una linea orizzontale con una label che coincide con il valore di "dist".
    Se ridimensiono la linea come voglio il valore di dist non cambia.
    Cosa sbaglio?
  • Re: Image Processing

    Sembra che cancelli il puntatore alla distanza quando si chiude l'immagine.
    Comunque, dato che ti serve una volta sola, o comunque poche volte, dopo che hai spostato la linea, clicca con il tasto destro e poi salva nel workspace. Ti salva una variabile che si chiama distance (o come vuoi tu) che contiene la distanza.
    Se poi invece ti serve nell'altro modo, cerchiamo di capire perchè non funziona.
  • Re: Image Processing

    Ok, mi crea la variabile "distance" e sono contento.

    adesso vorrei prendere anche le coordinate del pixel centrale e per farlo riciclo questo codice da un altro script:
    
    disp('Left mouse button picks points.')
    disp('Right mouse button picks last point.')
    but = 1;
    
    [selectedButton,dlgShown]=uigetpref('mygraphics',... % Group
        'savefigurebeforeclosing',...                 % Preference
        'Choosing frame origin',...                   % Window title
        {'Mouse click on the origin '
        ''},...
        {'always','never';'Yes','No'},...             % Values and button strings
        'DefaultButton','Cancel',...                  % Default choice
        'HelpFcn','doc(''closereq'');');               % Callback for Help button
    
    if (strcmp(selectedButton, 'always') == 1)
        while but == 1
            always = 1;
            [xi,yi,but] = ginput(1);
            %plot(xi,yi,'ro')
            %n = n+1;
            %xy(:,n) = [xi;yi];
          msgbox('FRAME ORIGIN IS DEFINED !','color','r')  
        end
        
        
        % The new origin is
        X0 = xi;
        Y0 = yi;
    end
    
    if (strcmp(selectedButton, 'never') == 1)
        warndlg('FRAME ORIGIN NOT DEFINED !')
    end                          
    
    mi dici come ti sembra? si può fare di meglio?

    Il secondo step è quello di usare queste info su una seconda immagine e disegnare la griglia.
    Ora ci lavoro.
  • Re: Image Processing

    Ti basta una riga:
    figure();imshow(figura)
    [x,y]=ginput(1);
    Ti si apre l'immagine, clicchi sul punto che vuoi e in x e y ti salva le coordinate.
  • Re: Image Processing

    Per adesso funziona tutto, prendo le coordinate del centro e laa distanza tra due punti che rappresentano 1cm sulla griglia. Lui crea le tre variabili:
    1)xc = 408
    2)yc = 245
    3) distance= 410.5 (che dovrebbe essere la distanza in pixel tra i due punti)

    Poi carico la seconda immagine, faccio un resize perchè per qualche strano motivo è più grande dell'immagine di calibrazione e adesso dovrei passargli le coordinate del centro e plottare la griglia (che non può essere nera perchè l'immagine è tutta nera, magari rossa...)
    Quale istruzione mi consente di individuare il pixel di coordinate xc e yc nella nuova immagine?
  • Re: Image Processing

    Ti consiglierei intanto di farla bianca (se l'immagine è nera) poi appena il codice funziona gli cambi colore, dato che lavorare nelle immagini in scala di grigi è molto più semplice.

    Ripeto anche che devi considerare l'immagine come una semplicissima matrice quindi il punto dell'immagine con coordinate x,y sarà A(x,y), e se lo devi fare bianco fai A(x,y)=1;
    Per fare in modo che il range di valori dell'immagine sia tra 0 e 1 usa im2double(A), in modo che lo 0 corrisponda al nero e l'1 al bianco.
  • Re: Image Processing

    L'immagine che ho acquisita è già in scala di grigi (è acquisita come una matrice di interi a 16bit), devo ugualmente convertire il range di valori?
    Poi non capisco perchè ho dovuto aggiungere le istruzioni:
    xc=int64(xc);
    yc=int64(yc);
    per accedere al pixel centrale. Non salva le coordinate come interi?

    adesso, con Im(xc,yc)=1; dovrei aver fissato il centro, giusto?
    quindi vedo se riesco a fare la griglia.
  • Re: Image Processing

    Controlla il massimo valore dell'immagine max(A(:)) per capire qual'è il range. Se è maggiore di 1 (se è a 16 bit probabilmente il valore massimo sarà 2^16) allora usa im2double, altrimenti non c'è bisogno.

    Per il pixel centrale non saprei... dovrebbero essere interi, ma sembra che spesso uno dei due non lo sia. Al momento non ne conosco il motivo. Ma forse non va bene usare int64 perchè non ti permette di fare alcune operazioni.

    Con Im(xc,yc)=1; colori il pixel centrale di bianco. Dovrai usare xc e yc come punti di riferimento per disegnare la griglia. Usa semplicemente gli intervalli per selezionare righe e colonne e con due righe hai risolto.
    es. per disegnare le righe devi solo calcolarti da dove parte la prima riga e dove finisce l'ultima (considerando che hai le coordinate del centro e la distanza tra le righe):
    A(indice_riga_minimo:passo:indice_di_riga_massimo,:)
    e poi fai lo stesso per le colonne
  • Re: Image Processing

    La matrice ha valori maggiori di 1, quindi la converto.

    La griglia la costruisco sull'immagine convertita che si chiama Im che nel workspace è 577x821x3 double.
    Ora se voglio fare la griglia nel primo quadrante dovrei scrivere:
    Im(X0:passo:821, : )
    Im(1:passo:Y0, : )
    solo che mi dà errore sulla prima istruzione, dice ??? Index exceeds matrix dimensions.
  • Re: Image Processing

    Anche se è in scala di grigi ha tre canali (RGB). Per questo ha anche la terza dimensione. Per un'immagine a colori i tre canali sono ridondanti quindi puoi trasformarla in una matrice 2D. Prima di convertirla in double aggiungi: A=rgb2gray(A) e dovresti risolvere il problema.
  • Re: Image Processing

    Il codice è questo:
    
    Image = imread (Path_Image);
    
    %resize the image according Calibration
    Im_res = imresize(Image, [577 821]);
    
    %range di valori tra 0 e 1
    Im_res=rgb2gray(Im_res);
    Im = im2double(Im_res);
    
    imshow(Im_res)
    
    impixelinfo;     % Show pixel informations
    
    %pixel centrale bianco
    X0=uint16(X0);
    Y0=uint16(Y0);
    Im(X0,Y0)= 0;
    
    passo=distance/10; passo=uint16(passo);
    
    %%%%griglia
    figure (3)
    
    Im(X0:passo:821, :) 
    Im(1:passo:Y0, :)
    
    imshow(Im)
    
    e mi dà ancora l'errore sulla dimensione.
    Se invece metto
    Im(X0:passo:821) =1;
    Im(1:passo:Y0)=1;
    non dà errore ma non fa le righe.
  • Re: Image Processing

    Scusa, non ci avevo fatto caso. Stai confondendo le righe con le colonne. Le righe sono 577 mentre tu stai cercando di accedere alla riga 821, quindi ti da errore.
  • Re: Image Processing

    Ho capito l'errore grossolano (sono troppo scarso a programmazion )
    ho corretto così:

    Im(X0:passo:577, : )
    Im(1:passo:Y0,:)

    ma la griglia non la fa...
Devi accedere o registrarti per scrivere nel forum
27 risposte