Trovare quadrati nell'immagine


34

Ho bisogno di trovare i quadrati in un'immagine usando OpenCV (nessun problema con Matlab o qualsiasi altro, in genere quello che mi aspetto sono alcune idee).

Considera l'immagine di prova qui sotto:

inserisci qui la descrizione dell'immagine

Devo trovare accuratamente quei quadrati colorati nell'immagine sopra (non le lunghe strisce bianche).

Cosa ho fatto :

  • Ho applicato il metodo comune (fornito con i campioni OpenCV), ovvero trovare contorni in tutti i piani di colore, approssimarlo e verificare il numero di elementi = 4. Funziona fino a un certo punto, vengono rilevati pochi quadrati, specialmente quelli scuri.

  • Il passo successivo che ho fatto è stato la previsione . cioè questa disposizione è fissa . Quindi, se alcuni vengono ottenuti, posso prevederne altri. Ha anche funzionato in qualche misura. Ma la precisione era pessima.

Ma penso che la previsione non sia un buon metodo qui e non fornisce sempre risposte accurate come indicato dal primo passo.

Ciò che di cui ho bisogno :

1) Esistono altri metodi migliori per rilevare questi quadrati in modo più accurato? O più metodi?

Un punto importante è che qui il tempo non è un problema . L'algoritmo può essere lento, non importa. Ma l'accuratezza è il criterio principale.

A volte, le immagini possono essere molto più sfocate.

E uno dei maggiori problemi che ho riscontrato è che alcuni quadrati hanno un colore quasi simile a quello dello sfondo (controlla la colonna 3 primo e secondo quadrato).

In cerca di idee, grazie in anticipo

AGGIORNARE :

Di seguito è riportato il risultato più accurato che ho ottenuto:

inserisci qui la descrizione dell'immagine

Ovviamente, l'immagine del risultato viene leggermente ridimensionata.

AGGIORNAMENTO 2:

Ho fornito una soluzione molto migliore nella mia risposta di seguito: https://dsp.stackexchange.com/a/7526/818


il tuo background è sempre biancastro?

1
la mia idea era quella di calcolare la "saturazione" e soglie il sat img ma usando il tuo esempio non funziona molto bene (calcolo della saturazione come max (RG, RB, GB). Il fatto che alcuni quadrati assomiglino quasi allo sfondo fanno la cosa abbastanza difficile. Se tutte le tue immagini hanno lo stesso modello (lunghe strisce bianche con quadrati accanto a loro) dovresti considerare di trovare i bit più facili (come i quadrati veramente colorati o le strisce bianche) dedurre la posizione possibile per altri piazze e ... trova un modo per verificare se sono davvero lì o no. Tanto ma interessante! Puoi dare più immagini?

Bene, penso che questo non avrebbe dovuto essere spostato.
Junuxx,

1
Puoi fornire più immagini? Inoltre, cos'è questa cosa?
Andrey Rubshtein,

2
L'OP deve rispondere ad alcune domande. Forse lo sfondo bianco non è necessario. E che succede con la luce? Sarà così male? Mi sembrano solo complessità inutili.
Tae-Sung Shin

Risposte:


9

Un primo tentativo con Matlab:

im = imread('squares.jpg');
im2 = rgb2gray(im);

se = strel('disk', 15);

for i = 1:16;
    t = 60+i*5; % try out a range of bw thresholds to see what works best
    labelled = bwlabel(im2>t); % label regions in the BW image
    closed = imclose(labelled, se); % close small regions
    cleared = imclearborder(~closed,4); % clear regions touching the border
    subplot(4,4,i); 
    imshow(cleared); 
    title(['T = ' num2str(t)]);
end

Risultati nelle seguenti regioni:

regioni etichettate

Come puoi vedere, la selezione della soglia che determina il numero più alto di regioni (T = 120) darebbe già 7 posizioni corrette, alcune posizioni unite, un falso positivo e due falsi negativi.

Questo è stato un tentativo abbastanza semplice ma penso che dimostri che l'approccio funziona. Aggiungere alcune cose per spezzare le regioni allungate o farlo separatamente per ogni canale di colore sono solo un paio di cose che potresti fare per migliorare.

Sarebbe anche utile se fornissi altre immagini di prova.


8

Avevo provato qualcos'altro per migliorare il mio risultato in questione. La soluzione che segue si basa sul presupposto che il primo quadrato (arancione) sia sempre rilevato nel passaggio 1. Ed è pratico a causa del suo alto contrasto di colore rispetto allo sfondo. Anche il risultato che ho mostrato in questione l'ha rilevato correttamente

Passaggio 1: trova il maggior numero possibile di quadrati

Ho diviso l'immagine in piani R, G, B, H, S, V e ho impostato l'immagine di soglia per valori di soglia diversi come multipli di 25. Per ogni immagine, ho trovato dei quadrati in essa e li ho posizionati su una "maschera immagine" . Ho anche trovato l'altezza e la larghezza medie del quadrato.

immagine maschera (rilevati 7/12 quadrati totali):

maschera immagine

Passaggio 2: formare una griglia di quadrati

Successivamente ho trovato i centroidi di questi quadrati nell'immagine maschera. Li ha ordinati e ha trovato il centroide del primo quadrato (arancione). Dall'analisi ravvicinata, possiamo vedere che il divario tra due quadrati è un quadrato sia in direzione orizzontale che verticale. Quindi, in questo modo, ho creato una griglia di quadrati come sotto e l'ho chiamato ideal_squares (è solo un nome, non significa che questo sia l'output di cui ho bisogno):

quadrati_ideale:

immagine ideale

Passaggio 3: rimappa l'immagine ideal_image

Ora abbiamo i centroidi ideal_squares e i centroidi originali. Ho scoperto le corrispondenze corrette per ciascun centroide originale da ideal_centroids (prendendo la distanza euclidea tra di loro). Quindi ho usato Scipy interpolate.griddata per l'interpolazione e rimappato ideal_image secondo i valori del centroide (è quasi lo stesso della deformazione eseguita in queste domande e risposte: Come rimuovere i difetti di convessità in sudoku square e trasformazione delle immagini in OpenCV ). Quindi di seguito è l'output che ho ottenuto:

Produzione :

Immagine in uscita

Passaggio 4: OPPURE operare sopra l'output con l'immagine della maschera dal primo passaggio

uscita finale

Ora puoi vedere tutti i quadrati rilevati, ma con un problema menzionato di seguito:

Problema:

Guarda l'output del passaggio 3, ovvero l'immagine rimappata della griglia quadrata. Tranne due quadrati centrali, tutti gli altri quadrati vengono ritagliati. È un problema associato a questo rimappatura. Non sono sicuro di dove sia il problema, con scipy.interpolate.griddata () o cv2.remap (). Pensavo che l'intera immagine sarebbe stata deformata, ma non lo è. Si deforma solo l'immagine all'interno dei centroidi che abbiamo dato. Se posso correggerlo, l'output sarà OK.

Quindi, se qualcuno conosce una buona idea per questo, molto gradito !!!


5

Nota: questo metodo sarà molto lento.

Genera una maschera che assomiglia ai contorni di un oggetto ideale. Simile a questo:

maschera dell'oggetto

quindi fai scorrere (posizione, scala, rotazione) la maschera sull'immagine e abbinala al contorno dell'immagine reale (forse un po 'sfocata per ottenere una risposta più morbida) per calcolare quanto sono simili, la (posizione, scala, rotazione) con la massima risposta di somiglianza dovrebbe essere la (posizione, scala, rotazione) dell'oggetto reale.

Al metodo non dispiace che i quadrati si fondano con lo sfondo o anche con occlusioni parziali dell'oggetto, poiché considera l'intero oggetto.

Ho usato personalmente questo metodo con successo per rintracciare un muso e un baffo del mouse, ma avevo alcune presunzioni come se fosse vicino all'ultima posizione nota ecc. Ma penso che puoi ridurre lo spazio di ricerca applicando alcune ipotesi come: dimensioni possibili dell'oggetto nella telecamera, quanto lontano dal centro può essere o rotazione <10 gradi ecc.


5

Passaggio 1: qualunque immagine binaria finale che si sta ottenendo dall'analisi in piano B, G, R, H, S, V, in quell'immagine, esegua un algoritmo di conteggio BLOB.

Passaggio 2: trovare il blob più grande in base all'area o alla lunghezza del contorno. Dal momento che i tuoi blob saranno per lo più tipi di parallelogrammi, quindi area o contorno, ognuno lo farà.

Passaggio 3: con il BLOB più grande (poiché il BLOB più grande è il BLOB migliore che assomiglia ai quadrati del mondo reale) prova a trovare l'orientamento del BLOB ... questo puoi ottenere inserendo un rettangolo che si adatta meglio O puoi ottenere i punti d'angolo ... ottieni la pendenza delle linee che le uniscono (sia in senso orizzontale che verticale).

Passaggio 4: una volta ottenute le due pendenze, traccia due linee che attraversano l'asse del blob. per asse puoi fare la media dei punti d'angolo o puoi usare il centroide (centro di massa) ... Vorrei andare con la media dei punti d'angolo ...

Passaggio 5: poiché in ciascuna direzione orizzontale e verticale, la spaziatura è uguale (idealmente anche la spaziatura orizzontale e verticale sono uguali in quanto proviene dalla tua immagine quadrata ideale ma non lo supponiamo ..) è sufficiente individuare i possibili centroidi dell'altro parallelogrammi

LINEA INFERIORE: se un quadrato viene rilevato perfettamente, puoi creare l'intera griglia. Mantenere semplicemente i centri di marcatura a un intervallo di 2H (H = larghezza orizzontale del blob più grande) lungo l'asse orizzontale del blob più grande e ad un intervallo di 2V (V = altezza verticale del blob più grande) verticalmente lungo l'asse verticale del blob.

Alcune foto da supportare inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


1
+1 - Sarebbe bello se tu potessi implementarlo.
Abid Rahman K,

2
@AbidRahmanK Non è questo lo scopo di StackExchange. Domanda -> Risposta. Altrimenti ciò finirebbe per essere una fiera del lavoro.
Jan Krüger,

2

questa disposizione è fissa

Non so davvero che tipo di previsione hai fatto prima, ma hai provato a concentrarti sulle lunghe strisce bianche come radice. Quindi (se 3 colonne di quadrati sono uguali), puoi rilevare l'altezza di un quadrato (distanza tra le due strisce) e puoi rilevare l'area massima e minima (altezza e larghezza) nell'immagine.

Quindi, prova a rilevare il colore più comune all'interno di tutto il quadrato e impostalo su un'area "non quadrata". Il resto dovrebbe essere i quadrati che stai cercando.


Ho trovato 3-4 quadrati usando il metodo del contorno. Quindi ha l'altezza e la larghezza di ogni quadrato. Quindi ha verificato lo spazio tra i quadrati rilevati e ha ipotizzato che lo spazio tra loro fosse abbastanza grande da contenere un altro quadrato. Questa è la previsione che ho fatto.
Abid Rahman K

Alcuni quadrati hanno un colore quasi simile a quello dello sfondo. Quindi temo che saranno considerati come un'area non quadrata secondo il tuo metodo.
Abid Rahman K

Forse potresti provare a lavorare su ogni colonna per tracciare una curva in cui l'asse x sarebbe l'altezza (in pixel) nell'immagine e l'asse y sarebbe l'intensità. Quindi, potresti provare a trovare alcuni spigoli con la forma derivata.

questo è il rilevamento dei bordi, giusto? L'ho provato, ma non ho ottenuto buoni risultati.
Abid Rahman K

1
Sì lo è, ma potresti vedere da solo perché non riesce e forse isolare alcune regioni interessanti nella trama. A proposito, se trovi alcuni suggerimenti utili per risolvere il tuo problema, ti preghiamo di pubblicarli. Buona fortuna per le tue ricerche

0

Suggerirei di utilizzare la trasformazione di Hough, che è un algoritmo molto robusto per trovare forme parametriche semplici, ad esempio linee, cerchi, ecc. Il rilevamento delle linee sarebbe il migliore nel tuo caso. Potresti trovare almeno i lati delle lunghe strisce bianche; quindi, con qualsiasi algoritmo di estrazione di angoli (Harris o forse anche SIFT o SURF) potresti trovare angoli lungo quelle linee, anche usando il fatto che i quadrati sono approssimativamente equidistanti.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.