Entrambe le tue immagini contengono molte linee che non hanno nulla a che fare con il segno che stai cercando. E alcune di quelle linee sono più lunghe / hanno un contrasto più elevato rispetto alle linee che effettivamente desideri, quindi penso che il rilevamento delle linee del bordo (ad es. Usando una trasformazione hough o sommando i contrasti in orizzontale / verticale) non funzionerà.
Ma: il segno che stai cercando ha altre caratteristiche che dovrebbero essere più facili da rilevare:
- Il segno sullo sfondo ha una luminosità (quasi) costante
- Occupa un'area relativamente ampia dell'immagine
- È vicino al centro dell'immagine
Quindi stai cercando una grande area connessa con basso contrasto. Ho hackerato un algoritmo di prova di concetto in Mathematica. (Non sono un esperto di OpenCV, ma menzionerò la rispettiva funzione OpenCV quando li conosco.)
In primo luogo, utilizzo i filtri derivati gaussiani per rilevare l'entità del gradiente in ciascun pixel. Il filtro derivato gaussiano ha un'ampia apertura (11x11 pixel in questo caso), quindi è molto sensibile al rumore. Quindi normalizzo l'immagine del gradiente a media = 1, quindi posso usare le stesse soglie per entrambi i campioni.
src = Import["http://www.freeimagehosting.net/uploads/720da20080.jpg"];
pixels = ImageData[ColorConvert[src, "Grayscale"]];
gradient = Sqrt[GaussianFilter[pixels, 5, {1, 0}]^2 + GaussianFilter[pixels, 5, {0, 1}]^2];
gradient = gradient/Mean[Flatten[gradient]];
Implementazione OpenCV: è possibile utilizzare sepFilter2D
per il filtro effettivo, ma a quanto pare, è necessario calcolare i valori del kernel del filtro da soli .
Il risultato è simile al seguente:
In questa immagine, lo sfondo del segno è scuro e i bordi del segno sono luminosi. Quindi posso binarizzare questa immagine e cercare componenti connessi scuri.
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
Implementazione di OpenCV: il limite dovrebbe essere semplice, ma penso che OpenCV non contenga un'analisi dei componenti connessa - puoi usare flood fill o cvBlobsLib per questo.
Ora trova il BLOB più grande vicino al centro dell'immagine e trova lo scafo convesso (ho semplicemente usato il BLOB più grande che non è collegato allo sfondo, ma potrebbe non essere sufficiente per ogni immagine).
risultati: