c++ - Elaborazione delle immagini:miglioramento dell'algoritmo per il riconoscimento "Coca-Cola Can"




algorithm image-processing opencv (20)

Apprendimento approfondito

Raccogli almeno un centinaio di immagini contenenti lattine di coca cola, annota il riquadro di delimitazione attorno a loro come classi positive, includi bottiglie di cola e altri prodotti cola etichettandole come classi negative e oggetti casuali.

A meno che non si raccolga un set di dati di grandi dimensioni, eseguire il trucco dell'utilizzo di funzioni di deep learning per piccoli set di dati. Idealmente usando una combinazione di Support Vector Machines (SVM) con reti neurali profonde.

Una volta fornite le immagini a un modello di apprendimento approfondito precedentemente preparato (ad esempio GoogleNet), invece di utilizzare il livello decisionale (finale) della rete neurale per classificare, utilizza i dati dei livelli precedenti come funzioni per addestrare il classificatore.

OpenCV e Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV e SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html

Uno dei progetti più interessanti su cui ho lavorato negli ultimi due anni è stato un progetto sull'elaborazione delle immagini . L'obiettivo era quello di sviluppare un sistema in grado di riconoscere le lattine di Coca-Cola (notare che sto sottolineando la parola "lattine", vedrete perché in un minuto). Puoi vedere un esempio qui sotto, con la lattina riconosciuta nel rettangolo verde con scala e rotazione.

Alcuni vincoli sul progetto:

  • Lo sfondo potrebbe essere molto rumoroso.
  • La lattina potrebbe avere qualsiasi scala o rotazione o anche orientamento (entro limiti ragionevoli).
  • L'immagine potrebbe avere un certo grado di sfocatura (i contorni potrebbero non essere interamente dritti).
  • Ci potrebbero essere bottiglie di Coca-Cola nell'immagine e l'algoritmo dovrebbe solo rilevare il barattolo !
  • La luminosità dell'immagine può variare molto (quindi non è possibile fare affidamento su "troppo" sul rilevamento del colore).
  • La lattina potrebbe essere parzialmente nascosta ai lati o al centro e probabilmente parzialmente nascosta dietro una bottiglia.
  • Non ci potrebbe essere alcuna lattina nell'immagine, nel qual caso non dovevi trovare nulla e scrivere un messaggio che dicesse così.

Quindi potresti finire con cose complicate come questa (che in questo caso ha avuto il mio algoritmo totalmente fallito):

Ho fatto questo progetto un po 'di tempo fa e mi sono divertito molto a farlo, e ho avuto un'implementazione decente. Ecco alcuni dettagli sulla mia implementazione:

Lingua : fatto in C ++ usando la libreria OpenCV .

Pre-elaborazione : per la pre-elaborazione dell'immagine, ovvero la trasformazione dell'immagine in una forma più grezza da assegnare all'algoritmo, ho utilizzato 2 metodi:

  1. Modifica del dominio dei colori da RGB a HSV e filtraggio basato sulla tonalità "rossa", saturazione superiore a una determinata soglia per evitare colori arancioni e filtro di valore basso per evitare i toni scuri. Il risultato finale era un'immagine binaria in bianco e nero, in cui tutti i pixel bianchi rappresentavano i pixel che corrispondono a questa soglia. Ovviamente c'è ancora un sacco di schifezze nell'immagine, ma questo riduce il numero di dimensioni con cui devi lavorare.
  2. Filtraggio del rumore utilizzando il filtraggio mediano (prendendo il valore mediano del pixel di tutti i vicini e sostituendo il pixel con questo valore) per ridurre il rumore.
  3. Utilizzo di Canny Edge Detection Filter per ottenere i contorni di tutti gli elementi dopo 2 passaggi precedenti.

Algoritmo : l'algoritmo che ho scelto per questo compito è stato preso da this fantastico libro sull'estrazione di feature e chiamato Generalized Hough Transform (piuttosto diverso dalla normale Hough Transform). In pratica dice alcune cose:

  • Puoi descrivere un oggetto nello spazio senza conoscere la sua equazione analitica (che è il caso qui).
  • È resistente alle deformazioni dell'immagine come il ridimensionamento e la rotazione, in quanto testerà fondamentalmente l'immagine per ogni combinazione di fattore di scala e fattore di rotazione.
  • Usa un modello base (un modello) che l'algoritmo "apprenderà".
  • Ogni pixel rimasto nell'immagine del profilo voterà per un altro pixel che sarà presumibilmente il centro (in termini di gravità) dell'oggetto, in base a ciò che ha appreso dal modello.

Alla fine, si finisce con una mappa di calore dei voti, per esempio qui tutti i pixel del contorno della lattina voteranno per il proprio centro gravitazionale, quindi avrete molti voti nello stesso pixel corrispondente al centro, e vedrà un picco nella mappa di calore come di seguito:

Una volta ottenuto ciò, una semplice euristica basata sulla soglia può darti la posizione del pixel centrale, da cui puoi ricavare la scala e la rotazione e quindi tracciare il tuo piccolo rettangolo attorno ad esso (la scala finale e il fattore di rotazione saranno ovviamente relativi al tuo modello originale). In teoria almeno ...

Risultati : ora, mentre questo approccio ha funzionato nei casi di base, è stato gravemente carente in alcune aree:

  • È estremamente lento ! Non lo sottolineerò abbastanza. Era necessario quasi un giorno intero per elaborare le 30 immagini di prova, ovviamente perché avevo un fattore di ridimensionamento molto elevato per la rotazione e la traduzione, poiché alcune delle lattine erano molto piccole.
  • Era completamente perso quando le bottiglie erano nell'immagine e per qualche motivo quasi sempre trovavamo la bottiglia al posto del barattolo (forse perché le bottiglie erano più grandi, quindi avevano più pixel, quindi più voti)
  • Anche le immagini sfocate non andavano bene, poiché i voti finivano in pixel in posizioni casuali attorno al centro, finendo quindi con una mappa di calore molto rumorosa.
  • In-varianza nella traslazione e nella rotazione è stata ottenuta, ma non nell'orientamento, il che significa che non è stato riconosciuto un barattolo che non si trovava direttamente di fronte all'obiettivo della telecamera.

Puoi aiutarmi a migliorare il mio algoritmo specifico , utilizzando esclusivamente le funzionalità OpenCV , per risolvere i quattro problemi specifici menzionati?

Spero che alcune persone impareranno qualcosa anche da questo, dopotutto penso che non solo le persone che fanno domande dovrebbero imparare. :)


È necessario un programma che impari e migliori l'accuratezza della classificazione organicamente dall'esperienza.

Suggerirò un apprendimento approfondito, con l'apprendimento profondo questo diventa un problema banale.

È possibile riqualificare il modello v3 di lancio su Tensorflow:

Come reintegrare lo strato finale di Inception per nuove categorie .

In questo caso, addestrerai una rete neurale convoluzionale per classificare un oggetto come una lattina di coca-cola oppure no.


Un approccio alternativo potrebbe essere quello di estrarre le funzionalità (punti chiave) utilizzando la funzione di trasformazione invariante scala (SIFT) o le funzionalità avanzate Speeded Up (SURF).

È implementato in OpenCV 2.3.1.

Puoi trovare un buon esempio di codice usando le funzionalità di Features2D + Homography per trovare un oggetto conosciuto

Entrambi gli algoritmi sono invarianti rispetto al ridimensionamento e alla rotazione. Dal momento che funzionano con le funzioni, puoi anche gestire l' occlusion (purché siano visibili un numero sufficiente di punti chiave).

Fonte immagine: esempio di tutorial

L'elaborazione richiede alcune centinaia di ms per SIFT, SURF è un po 'più veloce, ma non è adatto per le applicazioni in tempo reale. ORB usa FAST che è più debole per quanto riguarda l'invarianza di rotazione.

I documenti originali


Rilevo i rettangoli rossi: RGB -> HSV, filtro rosso -> immagine binaria, close (dilatare e quindi erode, noto come imclose in matlab)

Quindi guarda attraverso i rettangoli dal più grande al più piccolo. I rettangoli che hanno rettangoli più piccoli in una posizione / scala nota possono essere rimossi entrambi (assumendo che le proporzioni della bottiglia siano costanti, il rettangolo più piccolo sarebbe un tappo della bottiglia).

Questo ti lascerebbe con rettangoli rossi, quindi dovrai in qualche modo rilevare i loghi per capire se sono un rettangolo rosso o una lattina di coca cola. Come l'OCR, ma con un logo conosciuto?


Problema divertente: quando ho dato un'occhiata alla tua immagine della bottiglia ho pensato che fosse anche una lattina. Ma, come umano, quello che ho fatto per dire la differenza è che poi ho notato che era anche una bottiglia ...

Quindi, per distinguere lattine e bottiglie, che ne dite di scannerizzare prima le bottiglie? Se ne trovi uno, maschera l'etichetta prima di cercare lattine.

Non è troppo difficile da implementare se stai già facendo delle lattine. Il vero svantaggio è che raddoppia il tempo di elaborazione. (Ma pensando in anticipo alle applicazioni del mondo reale, finirai per voler fare bottiglie comunque ;-)


Per accelerare le cose, vorrei approfittare del fatto che non ti viene chiesto di trovare un'immagine / oggetto arbitrario, ma in particolare uno con il logo Coca-Cola. Ciò è significativo perché questo logo è molto distintivo e dovrebbe avere una caratteristica, la firma invariante scala nel dominio della frequenza, in particolare nel canale rosso di RGB. Vale a dire, il modello alternato di rosso-a-bianco-rosso incontrato da una linea di scansione orizzontale (allenato su un logo allineato orizzontalmente) avrà un "ritmo" distintivo mentre passa attraverso l'asse centrale del logo. Quel ritmo si "accelera" o "rallenta" a diverse scale e orientamenti, ma rimarrà proporzionalmente equivalente. È possibile identificare / definire alcune dozzine di tali linee di scansione, sia orizzontalmente che verticalmente attraverso il logo e molte altre in diagonale, in uno schema a stella. Chiama queste "linee di scansione della firma".

La ricerca di questa firma nell'immagine di destinazione è una semplice questione di scansionare l'immagine in strisce orizzontali. Cerca una frequenza alta nel canale rosso (indicando il passaggio da una regione rossa a una bianca) e, una volta trovata, verifica se è seguita da uno dei ritmi di frequenza identificati nella sessione di allenamento. Una volta trovata una corrispondenza, conoscerai immediatamente l'orientamento e la posizione della linea di scansione nel logo (se tieni traccia di queste cose durante l'allenamento), quindi identificare i confini del logo da lì è banale.

Sarei sorpreso se questo non fosse un algoritmo linearmente efficiente, o quasi. Ovviamente non affronta la tua discriminazione in bottiglia, ma almeno avrai i tuoi loghi.

(Aggiornamento: per il riconoscimento delle bottiglie, cerco la coca (il liquido marrone) adiacente al logo, cioè all'interno della bottiglia, oppure, nel caso di una bottiglia vuota, cerco un cappuccio che avrà sempre il La stessa forma, dimensione e distanza dal logo sono in genere tutte bianche o rosse. Cerca una forma ellittica tinta unita dove dovrebbe essere un cappuccio, relativamente al logo. Non è infallibile, ovviamente, ma il tuo obiettivo qui dovrebbe essere trovare quelli facili in fretta .)

(Sono passati alcuni anni dai miei giorni di elaborazione delle immagini, quindi ho mantenuto questo suggerimento di alto livello e concettuale. Penso che potrebbe leggermente approssimare come un occhio umano potrebbe operare - o almeno come fa il mio cervello!)


Guardando la forma

Date un'occhiata alla forma della porzione rossa della lattina / bottiglia. Notate come la lattina si assottiglia leggermente in alto mentre l'etichetta della bottiglia è diritta. È possibile distinguere tra questi due confrontando la larghezza della porzione rossa per tutta la sua lunghezza.

Guardando in evidenza

Un modo per distinguere tra bottiglie e lattine è il materiale. Una bottiglia è di plastica mentre una lattina è in metallo di alluminio. In situazioni sufficientemente illuminate, osservare la specularità sarebbe un modo per raccontare un'etichetta di bottiglia da un'etichetta di lattina.

Per quello che posso dire, è così che un umano direbbe la differenza tra i due tipi di etichette. Se le condizioni di illuminazione sono scarse, ci sarà sicuramente qualche incertezza nel distinguere le due comunque. In tal caso, dovresti essere in grado di rilevare la presenza della bottiglia trasparente / traslucida stessa.


Forse troppi anni di ritardo, ma comunque una teoria da provare.

Il rapporto tra il rettangolo di delimitazione della regione del logo rosso e la dimensione complessiva della bottiglia / lattina è diverso. Nel caso di Can, dovrebbe essere 1: 1, mentre sarà diverso in quello della bottiglia (con o senza cap). Questo dovrebbe rendere facile la distinzione tra i due.

Aggiornamento: la curvatura orizzontale della regione del logo sarà diversa tra la lattina e la bottiglia a causa della rispettiva differenza di dimensioni. Questo potrebbe essere particolarmente utile se il tuo robot ha bisogno di prendere la lattina / bottiglia, e tu decidi di conseguenza il grip.


Le prime cose che cercherò sono di colore ROSSO, quando si esegue il rilevamento degli occhi rossi in un'immagine: c'è una certa gamma di colori da rilevare, alcune caratteristiche a riguardo considerando l'area circostante e ad esempio la distanza dall'altra è infatti visibile nell'immagine.

1: La prima caratteristica è il colore e il rosso è molto dominante. Dopo aver rilevato la Coca Cola Red ci sono diversi elementi di interesse 1A: Quanto è grande questa area rossa (è di una quantità sufficiente per determinare una vera lattina o meno - 10 pixel non è probabilmente sufficiente), 1B: Contiene il colore dell'etichetta - "Coca-Cola" o onda. 1B1: C'è abbastanza da considerare un'alta probabilità che si tratti di un'etichetta.

L'articolo 1 è una sorta di scorciatoia - pre-processo se quel moccio si trova nell'immagine - vai avanti.

Quindi, se questo è il caso, posso quindi utilizzare quel segmento della mia immagine e iniziare a guardare un po 'più di zoom dall'area in questione - fondamentalmente guardare la regione circostante / i bordi ...

2: Data l'ID dell'area dell'immagine sopra in 1 - verifica i punti circostanti [bordi] dell'oggetto in questione. A: C'è quello che sembra essere un barattolo o un fondo - argento? B: Una bottiglia potrebbe sembrare trasparente, ma lo stesso potrebbe essere un tavolo di vetro - quindi c'è un tavolo di vetro / una mensola o un'area trasparente - in tal caso ci sono più uscite possibili. Una bottiglia POTREBBE avere un tappo rosso, potrebbe non, ma dovrebbe avere la forma della parte superiore della bottiglia / viti per filettare, o un tappo. C: Anche se questo fallisce A e B può ancora essere un possibile - parziale .. Questo è più complesso quando è parziale perché una bottiglia parziale / parziale può sembrare uguale, quindi un po 'più di elaborazione del bordo della regione Rossa a bordo .. una piccola bottiglia potrebbe essere di dimensioni simili ..

3: Dopo l'analisi di cui sopra, cioè quando guarderei il lettering e il logo dell'onda, perché posso orientare la mia ricerca per alcune delle lettere nelle parole Come potreste non avere tutto il testo a causa del non avere tutto il può, l'onda si allinea in alcuni punti al testo (distanza saggia) in modo da poter cercare quella probabilità e sapere quali lettere dovrebbero esistere in quel punto dell'onda a distanza x.


Non è difficile neanche per gli umani distinguere tra una bottiglia e una lattina nella seconda immagine (a condizione che la regione trasparente della bottiglia sia nascosta)?

Sono quasi la stessa eccezione per una regione molto piccola (cioè, la larghezza nella parte superiore della lattina è un po 'piccola mentre l'involucro della bottiglia ha la stessa larghezza in tutto, ma un piccolo cambiamento vero?)

La prima cosa che mi è venuta in mente è stata controllare la parte superiore rossa della bottiglia. Ma è ancora un problema, se non c'è il massimo per la bottiglia, o se è parzialmente nascosto (come detto sopra).

La seconda cosa che pensavo riguardava la trasparenza della bottiglia. OpenCV ha alcuni lavori per trovare oggetti trasparenti in un'immagine. Controlla i link qui sotto.

In particolare, guarda questo per vedere con quale precisione rilevano il vetro:

Vedi il loro risultato di implmentazione:

Dicono che è l'implementazione del documento "A Geodesic Active Contour Framework for Finding Glass" di K. McHenry e J. Ponce, CVPR 2006 .

Potrebbe essere utile nel tuo caso un po ', ma il problema sorge di nuovo se la bottiglia è piena.

Quindi penso che qui, puoi cercare prima il corpo trasparente delle bottiglie o una regione rossa collegata a due oggetti trasparenti lateralmente che è ovviamente la bottiglia. (Quando si lavora idealmente, un'immagine come segue.)

Ora puoi rimuovere la regione gialla, cioè l'etichetta della bottiglia ed eseguire l'algoritmo per trovare la lattina.

Ad ogni modo, questa soluzione ha anche diversi problemi come nelle altre soluzioni.

  1. Funziona solo se la tua bottiglia è vuota. In tal caso, dovrai cercare la regione rossa tra i due colori neri (se il liquido Coca Cola è nero).
  2. Un altro problema se la parte trasparente è coperta.

Ma comunque, se non ci sono nessuno dei problemi sopra nelle immagini, questo sembra essere un modo migliore.


Sono in ritardo di alcuni anni nel rispondere a questa domanda. Con lo stato dell'arte spinto ai limiti dalla CNN negli ultimi 5 anni, non avrei mai usato OpenCV per svolgere questo compito ora! ( So che hai specificamente desiderato le funzionalità di OpenCv nella domanda ) Ritengo che gli algoritmi di rilevamento degli oggetti come Faster-RCNN, YOLO, SSD, ecc., Possano affrontare questo problema con un margine significativo rispetto alle funzionalità di OpenCV. Se dovessi affrontare questo problema ora (dopo 6 anni !!) utilizzerei sicuramente Faster-RCNN .


In alternativa a tutte queste belle soluzioni, puoi addestrare il tuo classificatore e rendere l'applicazione robusta agli errori. Ad esempio, è possibile utilizzare Haar Training , fornendo un buon numero di immagini positive e negative del proprio target.

Può essere utile estrarre solo lattine e può essere combinato con il rilevamento di oggetti trasparenti.


C'è un pacchetto per la visione artificiale chiamato HALCON di MVTec i cui demo potrebbero darti buone idee sugli algoritmi. Esistono molti esempi simili al tuo problema che potresti eseguire in modalità demo e poi guardare gli operatori nel codice e vedere come implementarli dagli operatori OpenCV esistenti.

Ho usato questo pacchetto per prototipare rapidamente algoritmi complessi per problemi come questo e poi scoprire come implementarli usando le funzionalità OpenCV esistenti. In particolare per il tuo caso potresti provare a implementare in OpenCV la funzionalità incorporata nell'operatore find_scaled_shape_model . Alcuni operatori indicano il documento scientifico sull'implementazione dell'algoritmo che può aiutare a scoprire come fare qualcosa di simile in OpenCV. Spero che questo ti aiuti...


Mi piace la tua domanda, indipendentemente dal fatto che sia fuori tema o no: P

Un lato interessante; Ho appena completato un argomento nella mia laurea in cui abbiamo coperto la robotica e la visione artificiale. Il nostro progetto per il semestre è stato incredibilmente simile a quello che descrivi.

Abbiamo dovuto sviluppare un robot che utilizzava un Kinect Xbox per rilevare bottiglie di coca cola e lattine su qualsiasi orientamento in una varietà di condizioni di illuminazione e ambientali. La nostra soluzione prevedeva l'uso di un filtro passa banda sul canale Hue in combinazione con la trasformazione del cerchio degli assi. Siamo stati in grado di limitare un po 'l'ambiente (potremmo scegliere dove e come posizionare il robot e il sensore Kinect), altrimenti avremmo usato le trasformazioni SIFT o SURF.

Puoi leggere il nostro approccio sul mio blog post sull'argomento :)


Mi piace la sfida e volevo dare una risposta, che risolve il problema, penso.

  1. Estrai funzionalità (punti chiave, descrittori come SIFT, SURF) del logo
  2. Abbina i punti con un'immagine del modello del logo (usando Matcher come Brute Force)
  3. Stima le coordinate del corpo rigido (problema PnP - SolvePnP)
  4. Stimare la posizione del cappuccio in base al corpo rigido
  5. Fai la retroproiezione e calcola la posizione dei pixel dell'immagine (ROI) del tappo del flacone (presumo tu abbia i parametri intrinseci della fotocamera)
  6. Verifica con un metodo se il tappo è presente o meno. Se c'è, allora questa è la bottiglia

Il rilevamento del tappo è un altro problema. Può essere complicato o semplice. Se fossi in te, vorrei semplicemente controllare l'istogramma di colore nel ROI per una decisione semplice.

Per favore, dai il feedback se sbaglio. Grazie.


Questa potrebbe essere un'idea molto ingenua (o potrebbe non funzionare affatto), ma le dimensioni di tutte le lattine di coca sono fisse. Così può essere se la stessa immagine contiene sia una lattina che una bottiglia, quindi puoi distinguerle in base alle dimensioni (le bottiglie saranno più grandi). Ora a causa della profondità mancante (ad esempio la mappatura 3D alla mappatura 2D) è possibile che una bottiglia possa apparire ridotta e non ci sia una differenza di dimensioni. È possibile recuperare alcune informazioni sulla profondità utilizzando stereo-imaging e quindi ripristinare le dimensioni originali.


Si prega di dare un'occhiata al tracker Predator di Zdenek Kalal. Richiede un po 'di allenamento, ma può imparare attivamente come l'oggetto tracciato guarda a diversi orientamenti e scale e lo fa in tempo reale!

Il codice sorgente è disponibile sul suo sito. È in MATLAB , ma forse c'è un'implementazione Java già fatta da un membro della comunità. Ho implementato con successo la parte tracker di TLD in C #. Se ricordo bene, TLD utilizza Ferns come rilevatore di punti chiave. Io uso invece SURF o SIFT (già suggerito da @stacker) per riacquisire l'oggetto se è stato perso dal tracker. Il feedback del tracker facilita la costruzione nel tempo di un elenco dinamico di modelli di vaglio / surf che con il tempo consentono di riacquisire l'oggetto con una precisione molto elevata.

Se sei interessato alla mia implementazione C # del tracker, sentiti libero di chiedere.


Se ti interessa essere in tempo reale, allora quello di cui hai bisogno è aggiungere un filtro di pre-elaborazione per determinare cosa viene scansionato con materiale pesante. Un buon filtro di pre-elaborazione veloce, in tempo reale, che ti permetterà di scansionare cose che sono più probabilità di essere una lattina di coca-cola che non prima di passare a cose più incerte è qualcosa del genere: cerca l'immagine per le patch più grandi di colore che sono una certa tolleranza lontano dalla sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) della tua lattina di coca-cola. Inizia con una tolleranza cromatica molto rigida e procedi con tolleranze cromatiche più tolleranti. Quindi, quando il tuo robot esaurisce il tempo assegnato per elaborare il frame corrente, utilizza le bottiglie attualmente disponibili per i tuoi scopi. Tieni presente che dovrai modificare i colori RGB in sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) per ottenerli correttamente.

Inoltre, questo gona sembra davvero stupido, ma hai fatto in modo di attivare le ottimizzazioni del compilatore -oFast quando hai compilato il tuo codice C?


Ci sono un sacco di descrittori di colori usati per riconoscere gli oggetti, la carta qui sotto ne confronta molti. Sono particolarmente potenti se combinati con SIFT o SURF. SURF o SIFT da soli non sono molto utili in un'immagine di una coca cola in quanto non riconoscono molti punti di interesse, per cui è necessario disporre delle informazioni sul colore. Io uso BIC (Border / Interior Pixel Classi fi cation) con SURF in un progetto e ha funzionato benissimo per riconoscere gli oggetti.

Descrittori di colore per il recupero di immagini Web: uno studio comparativo


Il trailing-return-type arriva dopo cv- e qualifica-ref di una funzione membro non statica. Ciò significa che l'esempio nella domanda è lo stesso di T const f(...); .

§8.4.1 [dcl.fct.def.general] p2

Il dichiaratore in una definizione di funzione deve avere la forma

D1 ( parametro-dichiarazione-clausola ) cv-qualificatore-seq opt ref-qualificatore opt -eccezione-specifica opt -attributo-specifier-seq opt trailing-return-type opt

Per dichiarare una funzione membro const , si scriverebbe auto f(...) const -> T const; .





c++ algorithm image-processing opencv