Una de las principales fuentes de datos para el servicio Yandex.Maps son las imágenes satelitales. Para facilitar el trabajo con el mapa, los objetos están marcados con polígonos en las imágenes: bosques, estanques, calles, casas, etc. Por lo general, los cartógrafos se dedican al marcado. Decidimos ayudarlos y enseñarles a la computadora a agregar polígonos de casas sin la participación de personas.
Para operaciones con imágenes cumple con el campo de TI, que se llama visión por computadora. En los últimos años, la mayoría de las tareas en esta área se han resuelto con mucho éxito utilizando redes neuronales. Hoy les diremos a los lectores de Habr sobre nuestra experiencia de usar redes neuronales en el mapeo.
En primer lugar, entrenaremos una red neuronal, que participará en la segmentación semántica, es decir, determinará si cada punto de la imagen de satélite está relacionado con la casa. ¿Por qué la segmentación semántica y no solo la detección de objetos? Cuando se resuelva el problema de detección, obtendremos en la salida un conjunto de rectángulos, además específicos: dos lados son verticales, dos son horizontales. Y las casas generalmente se rotan en relación con los ejes de la imagen, y algunos edificios también tienen una forma compleja.
La tarea de segmentación semántica ahora está siendo resuelta por varias redes (
FCN ,
SegNet ,
UNet , etc.). Solo necesita elegir cuál es el mejor para nosotros.
Una vez recibida la máscara de la imagen satelital, seleccionamos grupos de puntos suficientemente grandes que pertenecen a las casas, los reunimos en áreas conectadas y presentamos los límites de las áreas en forma de vector en forma de polígonos.
Está claro que la máscara no será absolutamente precisa, lo que significa que las casas cercanas se pueden unir en un área conectada. Para hacer frente a este problema, decidimos capacitar más a la red. Ella encontrará en la imagen las costillas (los límites de las casas) y separará los edificios que están pegados.
Entonces, tal esquema surgió:
No descartamos por completo las redes de detección y probamos
Mask R-CNN . Su ventaja en comparación con la segmentación habitual es que la máscara R-CNN detecta objetos y genera una máscara, por lo que no hay necesidad de dividir la máscara común en áreas conectadas. Bueno, menos (como sin él) en la resolución fija de la máscara de cada objeto, es decir, para casas grandes con un borde complejo, este borde obviamente se simplificará.
Las herramientas
Luego fue necesario decidir sobre las herramientas. Aquí todo era bastante obvio:
OpenCV es el más adecuado para tareas de visión por computadora. La elección de las redes neuronales es algo más amplia. Nos instalamos en
Tensorflow . Sus ventajas:
- un conjunto bastante desarrollado de "cubos" listos para usar desde los cuales puede ensamblar sus redes;
- Python API, conveniente para crear rápidamente una estructura de red y para capacitación;
- Se puede utilizar una red entrenada en su programa a través de una interfaz C ++ (muy pobre en comparación con la parte de Python, pero suficiente para ejecutar redes preparadas).
Para el entrenamiento y otras computadoras pesadas, planeamos usar Nirvana, la maravillosa plataforma Yandex de la
que ya hablamos .
Datacet
El ochenta por ciento de éxito en trabajar con una red neuronal consiste en un buen conjunto de datos. Entonces, para empezar, deberíamos haber ensamblado tal conjunto de datos. Yandex tiene una gran cantidad de imágenes de satélite con objetos ya marcados. Todo parece ser simple: solo suba estos datos y recójalos en un conjunto de datos. Sin embargo, hay una advertencia.
Refinar conjunto de datos
Cuando una persona busca una casa en una imagen satelital, lo primero que ve es el techo. Pero la altura de las casas varía, el satélite puede tomar el mismo terreno desde diferentes ángulos, y si colocamos un polígono correspondiente al techo en el mapa vectorial, no hay garantía de que el techo no se vaya cuando se actualice la imagen. Pero la base está excavada en el suelo y, desde cualquier ángulo que la quite, todo el tiempo permanece en un solo lugar. Es por eso que las casas en el vector Yandex.Map están marcadas "en los cimientos". Esto es correcto, pero para la tarea de segmentar imágenes es mejor enseñar a la red a buscar techos: la esperanza de que la red esté capacitada para reconocer los cimientos es muy pequeña. Por lo tanto, en el conjunto de datos, todo debe estar marcado en los techos. Por lo tanto, para crear un buen conjunto de datos, necesitamos aprender cómo cambiar el diseño vectorial de las casas desde los cimientos hasta los techos.
Intentamos no cambiar, pero la calidad no era muy buena, y esto es comprensible: los ángulos de disparo del satélite son diferentes, las alturas de las casas son diferentes, como resultado, en las fotografías la base se movió en diferentes direcciones y a diferentes distancias del techo. La red se pierde de tanta variedad y, en el mejor de los casos, entrena para algo intermedio, en el peor de los casos, para algo incomprensible. Además, la red para la segmentación semántica produce un resultado similar a algo aceptable, pero al buscar bordes, la calidad disminuye drásticamente.Enfoque de trama
Desde que entramos en el campo de la visión por computadora, lo primero que hicimos fue probar un enfoque relevante para esta visión por computadora. Primero, el mapa vectorial está rasterizado (los polígonos de las casas se dibujan con líneas blancas sobre fondo negro),
el filtro Sobel selecciona los bordes en la imagen de satélite. Y luego hay un desplazamiento de dos imágenes entre sí, lo que maximiza la correlación entre ellas. Los bordes después del filtro Sobel son bastante ruidosos, por lo tanto, si este enfoque se aplica a un edificio, no siempre se obtiene un resultado aceptable. Sin embargo, el método funciona bien en territorios con edificios de la misma altura: si busca un desplazamiento inmediatamente sobre un área grande de la imagen, el resultado será más estable.
Enfoque "geométrico"
Si el territorio se construye no con el mismo tipo, sino con varias casas, el método anterior no funcionará. Afortunadamente, a veces sabemos la altura de los edificios en el mapa vectorial de Yandex y la posición del satélite durante el disparo. Por lo tanto, podemos usar el conocimiento escolar de geometría y calcular dónde y a qué distancia se moverá el techo en relación con la base. Este método ha mejorado el conjunto de datos en áreas con edificios de gran altura.
Enfoque "manual"
La forma más lenta: arremangarse, destapar el mouse, mirar el monitor y cambiar manualmente el diseño vectorial de las casas desde los cimientos hasta los techos. La técnica trae un resultado que es simplemente sorprendente en calidad, pero no se recomienda usarlo en grandes cantidades: los desarrolladores que se dedican a tales tareas rápidamente caen en la apatía y pierden interés en la vida.
Red neuronal
Al final, obtuvimos suficientes imágenes de satélite, bien marcadas en los techos. Entonces, hubo una oportunidad de entrenar la red neuronal (por ahora, sin embargo, no para la segmentación, sino para mejorar el diseño de otras imágenes de satélite). Y lo hicimos
Los datos de entrada de la red neuronal convolucional fueron una imagen satelital y una marca rasterizada desplazada. En la salida, recibimos un vector bidimensional: desplazamientos verticales y horizontales.
Con la ayuda de una red neuronal, encontramos el desplazamiento necesario, lo que nos permitió lograr buenos resultados en edificios para los que la altura no está indicada. Como resultado, redujimos significativamente la corrección de marcado manual.
Diferentes territorios - diferentes casas
Hay muchos territorios y estados interesantes en Yandex.Maps. Pero incluso en Rusia, las casas son extremadamente diversas, lo que afecta su aspecto en las imágenes satelitales. Por lo tanto, debe reflejar la diversidad en el conjunto de datos. E inicialmente no entendimos realmente cómo hacer frente a todo este esplendor. ¿Recopilar un gran conjunto de datos y luego entrenar una red en él? ¿Crea su propio conjunto de datos para cada tipo de desarrollo (condicional) y forma una red separada? ¿Entrenar una determinada red central y luego entrenarla para un tipo específico de desarrollo?
Empíricamente, encontramos que:
- Sin lugar a dudas, es necesario expandir el conjunto de datos para diferentes tipos de edificios en los que se planea utilizar la herramienta. Una red capacitada en un tipo es capaz de distinguir edificios de otro tipo, aunque de manera muy pobre.
- Es mejor entrenar una gran red en todo el conjunto de datos. Se generaliza bastante bien a varios territorios. Si entrena redes separadas para cada tipo de desarrollo, la calidad seguirá siendo la misma o apenas mejorará. Por lo tanto, no tiene sentido implementar diferentes redes para diferentes territorios. Además, esto requiere más datos y un clasificador adicional del tipo de desarrollo.
- Si usa redes antiguas al agregar nuevos territorios a los datos, las redes aprenden mucho más rápido. Volver a entrenar redes antiguas en datos extendidos genera aproximadamente el mismo resultado que entrenar una red desde cero, pero requiere mucho menos tiempo.
Opciones de solucion
Segmentación semántica
La segmentación semántica es una tarea bastante bien investigada. Después de la aparición del artículo de
Redes totalmente convolucionales , se resuelve principalmente mediante redes neuronales. Todo lo que queda es elegir una red (consideramos
FCN ,
SegNet y
UNet ), pensar si necesitamos trucos adicionales como CRF en la salida y decidir cómo y con qué función de error se capacitará la capacitación.
Como resultado, nos decidimos por una arquitectura similar a U-Net con una función de
intersección generalizada sobre unión como una función de error. Para el entrenamiento, cortamos las imágenes satelitales y sus marcas correspondientes (por supuesto, rasterizadas) en cuadrados y los ensamblamos en conjuntos de datos. Resultó bastante agradable, y a veces bien.
En los territorios con edificios individuales, la segmentación semántica fue suficiente para pasar a la siguiente etapa: la vectorización. Donde el edificio es denso, las casas a veces se juntan en un área cohesiva. Tomó separarlos.
Detección de bordes
Para hacer frente a esta tarea, puede encontrar los bordes en la imagen. Para detectar bordes, también decidimos entrenar la red (los algoritmos de búsqueda de bordes que no usan redes neuronales son claramente una cosa del pasado). Se formó una red de tipo HED, que se describe en
Detección de bordes anidada holísticamente . En el artículo original, la red recibió capacitación sobre el conjunto de datos BSDS-500, en el que todos los bordes están marcados en las imágenes. Una red entrenada encuentra todos los bordes pronunciados: los límites de las casas, carreteras, lagos, etc. Esto ya es suficiente para separar los edificios cercanos. Pero decidimos ir más allá y usar el mismo conjunto de datos para el entrenamiento que para la segmentación semántica, pero al rasterizar, no pinte los polígonos completos de los edificios, sino que dibuje solo sus límites.
El resultado fue tan abrumadoramente hermoso que decidimos vectorizar los edificios directamente por los bordes recibidos de la red. Y sucedió bastante.
Detección de vértices
Como una red como HED dio un excelente resultado en los bordes, decidimos entrenarla para detectar vértices. De hecho, tenemos una red con pesos generales en capas convolucionales. Tenía dos salidas al mismo tiempo: para bordes y para picos. Como resultado, hicimos otra versión de la vectorización de edificios, y en algunos casos mostró resultados bastante sanos.
Máscara r-cnn
Mask R-CNN es una expansión relativamente nueva de redes como Faster R-CNN. Máscara R-CNN busca objetos y selecciona una máscara para cada uno de ellos. Como resultado, para las casas obtenemos no solo rectángulos delimitadores, sino también una estructura refinada. Este enfoque se compara favorablemente con la detección simple (no sabemos cómo se ubica el edificio dentro del rectángulo) y la segmentación normal (varias casas pueden unirse en una, y no está claro cómo separarlas). Con la máscara R-CNN, ya no necesita pensar en trucos adicionales: es suficiente con vectorizar el borde de la máscara para cada objeto e inmediatamente obtener el resultado. También hay un signo negativo: el tamaño de la máscara para el objeto siempre es fijo, es decir, para edificios grandes, la precisión del diseño de píxeles será baja. El resultado de Mask R-CNN se ve así:
Probamos la máscara R-CNN en último lugar y nos aseguramos de que para algunos tipos de edificios este enfoque supere a otros.
Vectorización
Vectorización Rectángulo
Con toda la diversidad arquitectónica moderna, las casas en imágenes satelitales todavía parecen rectángulos. Además, para la masa de territorios, no es necesario marcar con polígonos complejos. Pero aun así quiero que se marquen las casas en el mapa. (Bueno, por ejemplo, una asociación hortícola: generalmente hay muchas casas allí, marcar manualmente no es tan importante, pero marcar con rectángulos en el mapa es muy bueno). Por lo tanto, el primer enfoque para la vectorización fue extremadamente simple.
- Tome la región ráster correspondiente a la "casa".
- Encuentre el rectángulo del área mínima que contiene esta área (por ejemplo, así: OpenCV :: minAreaRect ). El problema está resuelto.
Está claro que la calidad de este enfoque está lejos de ser ideal. Sin embargo, el algoritmo es bastante simple y en muchos casos funciona.
Vectorización de polígonos
Si la calidad de la segmentación es lo suficientemente buena, puede recrear con mayor precisión el contorno de la casa. En la mayoría de los edificios de forma compleja, los ángulos son en su mayoría correctos, por lo que decidimos reducir el problema a la tarea de construir un polígono con lados ortogonales. Resolviéndolo, queremos lograr dos objetivos a la vez: encontrar el polígono más simple y repetir la forma de los edificios con la mayor precisión posible. Estos objetivos entran en conflicto entre sí, por lo que debe introducir condiciones adicionales: limitar la longitud mínima de las paredes, la desviación máxima de la región ráster, etc.
El algoritmo que se nos ocurrió por primera vez se basó en la construcción de la proyección de puntos en líneas rectas:
- Encuentre el contorno de la región ráster correspondiente a una casa.
- Reduzca el número de puntos en el circuito simplificándolo, por ejemplo, con el algoritmo Douglas-Pecker .
- Encuentra el lado más largo del contorno. Es su ángulo de inclinación lo que determinará el ángulo de todo el futuro polígono ortogonal.
- Construya una proyección desde el siguiente punto de contorno hasta el lado anterior.
- Extienda el lado al punto de proyección. Si la distancia desde el punto hasta su proyección es mayor que la pared más corta del edificio, agregue el segmento resultante al contorno del edificio.
- Repita los pasos 4 y 5 hasta que se cierre el circuito.
Este algoritmo es extremadamente simple y produce resultados rápidamente, pero aún así el contorno del edificio a veces resulta ser bastante ruidoso. Al tratar de hacer frente a este problema, encontramos una
solución bastante interesante
para el problema, que utiliza una cuadrícula cuadrada en el espacio para aproximar el polígono. Descrito brevemente, el algoritmo consta de tres acciones:
- Construya una cuadrícula cuadrada en el espacio centrado en cero.
- En los puntos de la cuadrícula que se encuentran a una distancia determinada del contorno original, construya diferentes polígonos.
- Seleccione un polígono con un número mínimo de vértices.
Dado que el ángulo de rotación requerido de la cuadrícula no se conoce de antemano, es necesario clasificar varios valores, lo que afecta mal el rendimiento. Sin embargo, el algoritmo le permite lograr resultados visualmente más hermosos.
Mejora de vectorización
Si bien en realidad trabajamos con cada casa por separado. Cuando se completa la primera etapa, ya puede trabajar con la imagen como un todo y mejorar el resultado. Para esto, se ha agregado un algoritmo para el procesamiento posterior de un conjunto de polígonos. Utilizamos las siguientes heurísticas:
- Por lo general, las paredes de las casas adyacentes son paralelas. Además: con mayor frecuencia, las casas se pueden combinar en conjuntos, dentro de los cuales se alinean todos los elementos.
- Si las calles ya están marcadas en la imagen, es muy probable que los lados de los polígonos sean paralelos a las calles.
- Si los polígonos se cruzan, lo más probable es que tenga sentido mover los muros para que la intersección desaparezca.
Como resultado, apareció el siguiente algoritmo:
- Agrupamos las casas encontradas por la distancia entre ellas y el ángulo de rotación. Hacemos un promedio de las vueltas de los edificios en cada grupo. Repetimos hasta que la posición de los edificios deje de cambiar o hasta que las casas comiencen a desviarse demasiado de la posición inicial.
- Elegimos casas cerca de las carreteras, encontramos las más largas y cercanas a la carretera. Llevamos la casa al paralelismo del lado seleccionado y el camino.
- Eliminamos las intersecciones entre los polígonos, desplazando los lados de dos edificios que se cruzan en proporción al tamaño de los lados.
Resultado
Como resultado, obtuvimos una herramienta que puede reconocer edificios de varios tipos de edificios. Ayuda a los cartógrafos en su arduo trabajo: acelera significativamente la búsqueda de casas faltantes y rellena áreas nuevas, aún no cultivadas. Actualmente, se han agregado más de 800 mil objetos nuevos al Mapa de personas utilizando esta herramienta.
A continuación verá algunos ejemplos de reconocimiento.