Estoy tratando de encontrar los cuadros delimitadores de texto en una imagen y actualmente estoy usando este enfoque:
// calculate the local variances of the grayscale image
Mat t_mean, t_mean_2;
Mat grayF;
outImg_gray.convertTo(grayF, CV_32F);
int winSize = 35;
blur(grayF, t_mean, cv::Size(winSize,winSize));
blur(grayF.mul(grayF), t_mean_2, cv::Size(winSize,winSize));
Mat varMat = t_mean_2 - t_mean.mul(t_mean);
varMat.convertTo(varMat, CV_8U);
// threshold the high variance regions
Mat varMatRegions = varMat > 100;
Cuando se le da una imagen como esta:
Luego, cuando muestro varMatRegions
, obtengo esta imagen:
Como puede ver, combina el bloque de texto izquierdo con el encabezado de la tarjeta, para la mayoría de las tarjetas este método funciona muy bien, pero en las tarjetas más ocupadas puede causar problemas.
La razón por la que es malo que esos contornos se conecten es porque hace que el cuadro delimitador del contorno casi ocupe toda la tarjeta.
¿Alguien puede sugerir una forma diferente de encontrar el texto para garantizar una detección adecuada del texto?
200 puntos para quien pueda encontrar el texto en la tarjeta sobre estos dos.
fuente
Respuestas:
Puede detectar texto al encontrar elementos de borde cercano (inspirados en un LPD):
Uso:
Resultados:
a. elemento = getStructuringElement (cv :: MORPH_RECT, cv :: Size (17, 3));
si. elemento = getStructuringElement (cv :: MORPH_RECT, cv :: Size (30, 30));
Los resultados son similares para la otra imagen mencionada.
fuente
n
? Gracias por la solución, funciona muy bien.cv::Rect a;
. Ampliada por n:a.x-=n/2;a.y-=n/2;a.width+=n;a.height+=n;
.Usé un método basado en gradiente en el programa a continuación. Se agregaron las imágenes resultantes. Tenga en cuenta que estoy usando una versión reducida de la imagen para el procesamiento.
versión c ++
versión de python
fuente
rect
. Hay unopyrdown
, así que multipliquex, y, width, height
el númerorect
por 4.Aquí hay un enfoque alternativo que usé para detectar los bloques de texto:
A continuación se muestra el código escrito en python con pyopencv, debería ser fácil de portar a C ++.
La imagen original es la primera imagen en tu publicación.
Después del preprocesamiento (escala de grises, umbral y dilatación, así que después del paso 3) la imagen se veía así:
A continuación se muestra la imagen resultante ("contoured.jpg" en la última línea); los cuadros delimitadores finales para los objetos en la imagen se ven así:
Puede ver que el bloque de texto de la izquierda se detecta como un bloque separado, delimitado de su entorno.
Usando el mismo script con los mismos parámetros (excepto el tipo de umbral que se cambió para la segunda imagen como se describe a continuación), aquí están los resultados para las otras 2 tarjetas:
Afinando los parámetros
Los parámetros (valor umbral, parámetros de dilatación) se optimizaron para esta imagen y esta tarea (buscar bloques de texto) y se pueden ajustar, si es necesario, para encontrar otras imágenes de tarjetas u otros tipos de objetos.
Para el umbral (paso 2), utilicé un umbral negro. Para las imágenes donde el texto es más claro que el fondo, como la segunda imagen en su publicación, se debe usar un umbral blanco, así que reemplace el tipo de desplazamiento con
cv2.THRESH_BINARY
). Para la segunda imagen también utilicé un valor ligeramente más alto para el umbral (180). La variación de los parámetros para el valor umbral y el número de iteraciones para la dilatación dará como resultado diferentes grados de sensibilidad al delimitar objetos en la imagen.Encontrar otros tipos de objetos:
Por ejemplo, disminuir la dilatación a 5 iteraciones en la primera imagen nos da una delimitación más fina de los objetos en la imagen, encontrando aproximadamente todas las palabras en la imagen (en lugar de bloques de texto):
Conociendo el tamaño aproximado de una palabra, aquí descarté áreas que eran demasiado pequeñas (menos de 20 píxeles de ancho o alto) o demasiado grandes (más de 100 píxeles de ancho o alto) para ignorar objetos que probablemente no sean palabras, para obtener los resultados La imagen de arriba.
fuente
cv2.findContours
. DiceValueError: too many values to unpack
.cv2.findContours
devuelve 3 argumentos, y el código original captura solo 2.El enfoque de @ dhanushka mostró la mayor promesa, pero quería jugar en Python, así que seguí adelante y lo traduje por diversión:
Ahora para mostrar la imagen:
No es el más Pythonic de los scripts, pero traté de asemejarme lo más posible al código original de C ++ para que los lectores lo siguieran.
Funciona casi tan bien como el original. Estaré encantado de leer sugerencias sobre cómo podría mejorarse / repararse para parecerse completamente a los resultados originales.
fuente
drawContours
ese estado "La función dibuja contornos de contorno en la imagen si grosor> 0 o llena el área delimitada por los contornos si grosor <0". Está hecho para que podamos verificar la proporción de píxeles distintos de cero para decidir si el cuadro probablemente contiene texto.Puede probar este método desarrollado por Chucai Yi y Yingli Tian.
También comparten un software (que se basa en Opencv-1.0 y debe ejecutarse en la plataforma Windows) que puede usar (aunque no hay código fuente disponible). Generará todos los cuadros delimitadores de texto (mostrados en sombras de color) en la imagen. Al aplicar sus imágenes de muestra, obtendrá los siguientes resultados:
Nota: para hacer que el resultado sea más robusto, puede combinar aún más los cuadros adyacentes.
Actualización: si su objetivo final es reconocer los textos en la imagen, puede consultar gttext , que es un software gratuito de OCR y una herramienta de verificación de terreno para imágenes en color con texto. El código fuente también está disponible.
Con esto, puede obtener textos reconocidos como:
fuente
Versión JAVA del Código anterior: Gracias @William
Y use este código en la práctica:
fuente
Implementación de Python para la solución de @ dhanushka:
fuente
Esta es una versión C # de la respuesta de dhanushka usando OpenCVSharp
fuente
Esta es una versión VB.NET de la respuesta de dhanushka usando EmguCV .
Algunas funciones y estructuras en EmguCV necesitan una consideración diferente que la versión C # con OpenCVSharp
fuente