Vos deux images contiennent de nombreuses lignes qui n'ont rien à voir avec le signe que vous recherchez. Et certaines de ces lignes sont plus longues / ont un contraste plus élevé que les lignes que vous voulez réellement, donc je pense que la détection des lignes de bord (par exemple en utilisant une transformation de Hough ou en additionnant les contrastes horizontalement / verticalement) ne fonctionnera pas.
Mais: l'enseigne que vous recherchez présente d'autres caractéristiques qui devraient être plus faciles à détecter:
- Le fond du panneau a une luminosité (presque) constante
- Il occupe une zone relativement grande de l'image
- C'est près du centre de l'image
Vous recherchez donc une grande zone connectée à faible contraste. J'ai piraté un algorithme de validation de principe dans Mathematica. (Je ne suis pas un expert OpenCV, mais je mentionnerai la fonction OpenCV respective quand je les connais.)
Tout d'abord, j'utilise des filtres dérivés gaussiens pour détecter l'amplitude du gradient à chaque pixel. Le filtre dérivé gaussien a une grande ouverture (11x11 pixels dans ce cas), il est donc très insensible au bruit. Je normalise ensuite l'image du gradient pour signifier = 1, donc je peux utiliser les mêmes seuils pour les deux échantillons.
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]];
Implémentation OpenCV: Vous pouvez utiliser sepFilter2D
pour le filtrage réel, mais apparemment, vous devrez calculer vous-même les valeurs du noyau du filtre .
Le résultat ressemble à ceci:
Sur cette image, l'arrière-plan du panneau est sombre et les bordures du panneau sont lumineuses. Je peux donc binariser cette image et rechercher des composants connectés sombres.
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
Implémentation d'OpenCV: le seuillage devrait être simple, mais je pense qu'OpenCV ne contient pas d'analyse de composants connectés - vous pouvez utiliser soit le remplissage d'inondation ou cvBlobsLib pour cela.
Maintenant, il suffit de trouver le plus gros blob près du centre de l'image et de trouver la coque convexe (j'ai simplement utilisé le plus gros blob qui n'est pas connecté à l'arrière-plan, mais cela pourrait ne pas être suffisant pour chaque image).
Résultats: