Ambas imágenes contienen muchas líneas que no tienen nada que ver con el signo que está buscando. Y algunas de esas líneas son más largas / tienen un mayor contraste que las líneas que realmente desea, por lo que creo que detectar las líneas de borde (por ejemplo, usando una transformación de hough o sumando contrastes horizontal / verticalmente) no funcionará.
Pero: el signo que está buscando tiene otras características que deberían ser más fáciles de detectar:
- El fondo de la señal tiene un brillo (casi) constante
- Ocupa un área relativamente grande de la imagen.
- Está cerca del centro de la imagen.
Por lo tanto, está buscando una gran área conectada con bajo contraste. He pirateado un algoritmo de prueba de concepto en Mathematica. (No soy un experto en OpenCV, pero mencionaré la función de OpenCV correspondiente cuando los conozca).
Primero, uso filtros derivados de Gauss para detectar la magnitud del gradiente en cada píxel. El filtro derivado gaussiano tiene una apertura amplia (11x11 píxeles en este caso), por lo que es muy insensible al ruido. Luego normalizo la imagen de gradiente para que signifique = 1, de modo que pueda usar los mismos umbrales para ambas muestras.
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]];
Implementación de OpenCV: puede usar sepFilter2D
para el filtrado real, pero aparentemente, tendrá que calcular los valores del núcleo del filtro usted mismo .
El resultado se ve así:
En esta imagen, el fondo del letrero es oscuro y los bordes del letrero son brillantes. Entonces puedo binarizar esta imagen y buscar componentes conectados oscuros.
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
Implementación de OpenCV: los umbrales deben ser sencillos, pero creo que OpenCV no contiene análisis de componentes conectados; puede usar relleno de inundación o cvBlobsLib para eso.
Ahora, solo encuentre el blob más grande cerca del centro de la imagen y encuentre el casco convexo (simplemente he usado el blob más grande que no está conectado al fondo, pero que podría no ser suficiente para cada imagen).
Resultados: