{"id":11744,"date":"2026-04-11T20:21:11","date_gmt":"2026-04-11T18:21:11","guid":{"rendered":"https:\/\/bitacora.eniac2000.com\/?p=11744"},"modified":"2026-04-11T20:21:13","modified_gmt":"2026-04-11T18:21:13","slug":"fotogrametria-con-ia-deteccion-de-hallazgos-en-tiempo-real-durante-el-vuelo-modulo-de-auditoria-ia-con-yolov8-y-rtmp-sobre-el-stack-odm","status":"publish","type":"post","link":"https:\/\/bitacora.eniac2000.com\/?p=11744","title":{"rendered":"Fotogrametr\u00eda con IA: Detecci\u00f3n de hallazgos en tiempo real durante el vuelo. M\u00f3dulo de auditor\u00eda IA con YOLOv8 y RTMP sobre el stack ODM"},"content":{"rendered":"<div class=\"seriesmeta\">Esta entrada es la parte 7 de 7 de la serie <a href=\"https:\/\/bitacora.eniac2000.com\/?series=fotogrametria-asistida-por-ia\" class=\"series-1957\" title=\"Fotogrametr\u00eda asistida por IA\">Fotogrametr\u00eda asistida por IA<\/a><\/div>\n<p>Cuando empec\u00e9 esta serie de art\u00edculos, el objetivo era construir una aplicaci\u00f3n Android capaz de planificar y ejecutar misiones de fotogrametr\u00eda con el DJI Mini 3 Pro. Ese objetivo est\u00e1 cumplido desde la <a href=\"https:\/\/bitacora.eniac2000.com\/?p=11696\">Fase 2<\/a>, y las fases siguientes han ido refinando el resultado. Pero hay algo que el flujo fotogram\u00e9trico cl\u00e1sico no puede hacer por su propia naturaleza: <strong>detectar algo mientras el dron est\u00e1 volando<\/strong>. Las fotos se procesan despu\u00e9s de aterrizar, cuando el dron ya no est\u00e1 en el aire. Si hay una anomal\u00eda en el \u00e1rea inspeccionada \u2014una grieta, un intruso, un panel solar averiado\u2014 el operador no lo sabr\u00e1 hasta horas despu\u00e9s, cuando el modelo 3D est\u00e9 listo.<\/p>\n\n\n\n<p>El m\u00f3dulo que describo en este art\u00edculo cierra esa carencia. Es una extensi\u00f3n del servidor de procesado que ya describ\u00ed en el <a href=\"https:\/\/bitacora.eniac2000.com\/?p=11703\">art\u00edculo sobre la plataforma ODM<\/a>: a\u00f1ade un pipeline de v\u00eddeo en tiempo real que opera en paralelo al flujo fotogram\u00e9trico existente, sin interferir con \u00e9l, y que permite detectar hallazgos durante el vuelo y georreferenciarlos autom\u00e1ticamente sobre el ortomosaico.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"559\" src=\"https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/Gemini_Generated_Image_h43xylh43xylh43x-1024x559.png\" alt=\"\" class=\"wp-image-11745\" srcset=\"https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/Gemini_Generated_Image_h43xylh43xylh43x-1024x559.png 1024w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/Gemini_Generated_Image_h43xylh43xylh43x-300x164.png 300w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/Gemini_Generated_Image_h43xylh43xylh43x-768x419.png 768w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/Gemini_Generated_Image_h43xylh43xylh43x.png 1408w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Imagen conceptual de la detecci\u00f3n en tiempo real de hallazgos. Imagen generada con IA<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">La idea: dos flujos paralelos desde el mismo dron<\/h2>\n\n\n\n<p>El planteamiento arquitect\u00f3nico parte de una distinci\u00f3n clara entre dos tipos de datos que produce el dron simult\u00e1neamente: las <strong>fotograf\u00edas de alta resoluci\u00f3n<\/strong>, destinadas al procesado fotogram\u00e9trico diferido, y el <strong><em>stream<\/em> de v\u00eddeo en tiempo real<\/strong> que el MSDK v5 expone continuamente desde la c\u00e1mara. Hasta ahora, ese <em>stream<\/em> solo se usaba para la vista FPV en la pantalla del operador. El m\u00f3dulo de auditor\u00eda le da un segundo uso: lo ingesta en el servidor, lo analiza fotograma a fotograma con un modelo de detecci\u00f3n de objetos, y persiste los hallazgos georreferenciados en una base de datos espacial.<\/p>\n\n\n\n<p>Los dos flujos corren en paralelo y son completamente independientes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DJI Mini 3 Pro\n    \u2502\n    \u251c\u2500\u2500 Fotos JPEG \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba WebODM (procesado diferido)\n    \u2502                                      \u2502\n    \u2502                                      \u25bc\n    \u2502                             Ortomosaico \/ Nube de puntos\n    \u2502\n    \u2514\u2500\u2500 Stream v\u00eddeo H.264 \u2500\u2500\u25ba MediaMTX (RTMP) \u2500\u2500\u25ba YOLOv8\n              +                                         \u2502\n         Telemetr\u00eda GPS \u2500\u2500\u25ba audit-api \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba Hallazgo georreferenciado\n         (cada 500 ms)                                   \u2502\n                                                         \u25bc\n                                               Visor Leaflet + GeoJSON\n                                               sobre el ortomosaico<\/code><\/pre>\n\n\n\n<p>La clave de la georreferenciaci\u00f3n es la sincronizaci\u00f3n por <em>timestamp<\/em>: la <em>app<\/em> Android estampa cada fotograma de v\u00eddeo con su propio reloj local y env\u00eda telemetr\u00eda GPS con el mismo <em>timestamp<\/em> cada 500 ms. Cuando el procesador de IA detecta algo en un frame, consulta la base de datos para encontrar la posici\u00f3n GPS m\u00e1s cercana en tiempo, y esa coordenada se convierte en la ubicaci\u00f3n geogr\u00e1fica del hallazgo. La latencia RTMP \u2014t\u00edpicamente 1 a 3 segundos\u2014 no afecta a la precisi\u00f3n porque la fuente de verdad temporal es siempre el reloj de la app, no el del servidor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">La arquitectura: tres contenedores nuevos sobre el stack existente<\/h2>\n\n\n\n<p>El m\u00f3dulo se despliega como un <em>overlay<\/em> de Docker Compose sobre el <em>stack<\/em> ODM que ya estaba funcionando. La decisi\u00f3n de dise\u00f1o m\u00e1s importante fue no tocar nada del stack original: el <em>overlay<\/em> a\u00f1ade tres contenedores nuevos a la red Docker existente, modifica \u00fanicamente el <code>nginx.conf<\/code> para a\u00f1adir tres bloques <code>location<\/code>, y comparte la base de datos PostgreSQL ya existente a\u00f1adiendo cuatro tablas nuevas con <code>IF NOT EXISTS<\/code> para que el script sea completamente idempotente. Al terminar el despliegue, una verificaci\u00f3n sistem\u00e1tica confirm\u00f3 que todos los contenedores ODM preexistentes segu\u00edan funcionando exactamente igual, con sus datos intactos.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Red Docker interna: odm-stack_odm-net (172.20.0.0\/16)\n\n  Puerto 80 (nginx \u2014 punto de entrada \u00fanico)\n       \u2502\n       \u251c\u2500\u2500 \/         \u2192 WebODM UI        (sin cambios)\n       \u251c\u2500\u2500 \/cluster\/ \u2192 ClusterODM       (sin cambios)\n       \u251c\u2500\u2500 \/3d\/      \u2192 Potree           (sin cambios)\n       \u2514\u2500\u2500 \/audit\/   \u2192 audit-api        (NUEVO)\n\nM\u00f3dulo de auditor\u00eda (overlay sobre el stack existente):\n\n  Dron \u2500\u2500RTMP\u2500\u2500\u25ba \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 stream interno \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                 \u2502  audit-mediamtx  \u2502\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba\u2502 audit-           \u2502\n                 \u2502  :1935 (RTMP)    \u2502 graba .mp4     \u2502 ai-processor     \u2502\n                 \u2502  :8888 (HLS)     \u2502\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 (YOLOv8m)        \u2502\n                 \u2502  :8889 (WebRTC)  \u2502                \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                         \u2502 POST \/detections\n                                                              \u25bc\n  App \u2500\u2500telemetr\u00eda\u2500\u2500\u25ba POST \/audit\/telemetry \u2500\u2500\u25ba \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                                                 \u2502    audit-api         \u2502\n                                                 \u2502    (FastAPI :8001)   \u2502\n                                                 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                                                            \u2502 SQL async\n                                                            \u25bc\n                                                   odm-postgres (PostGIS)\n                                                   tablas: flights,\n                                                   drone_telemetry,\n                                                   ai_detections,\n                                                   odm_tasks<\/code><\/pre>\n\n\n\n<p>Cada contenedor tiene una responsabilidad bien acotada. <strong>MediaMTX<\/strong> recibe el stream RTMP del dron, lo redistribuye internamente para que el procesador de IA pueda consumirlo, y graba simult\u00e1neamente segmentos de 5 minutos en disco en formato MP4 sin recodificaci\u00f3n, con retenci\u00f3n autom\u00e1tica de 30 d\u00edas. <strong>audit-api<\/strong> es una API REST en FastAPI que gestiona los vuelos, recibe la telemetr\u00eda GPS de la <em>app<\/em>, georreferencia los hallazgos y los expone como GeoJSON. <strong>audit-ai-processor<\/strong> lee el stream de MediaMTX, aplica YOLOv8 fotograma a fotograma y notifica a la API cuando detecta algo por encima del umbral de confianza.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">El procesador de IA: YOLOv8 en CPU a 8 fps efectivos<\/h2>\n\n\n\n<p>El procesador de IA es el componente m\u00e1s interesante del m\u00f3dulo, y tambi\u00e9n el que m\u00e1s ajustes requiri\u00f3. El DL360 Gen8 no tiene GPU, as\u00ed que la inferencia se ejecuta \u00edntegramente en CPU. YOLOv8 en CPU tarda unos 120 ms por frame con el modelo nano y unos 400 ms con el medium, sobre im\u00e1genes de 1080p. Procesar los 30 fps del <em>stream<\/em> es inviable; la soluci\u00f3n es procesar uno de cada N <em>frames<\/em>, configurable mediante <code>FRAME_SKIP<\/code>. Con <code>FRAME_SKIP=5<\/code> y el modelo medium se procesan efectivamente unos 8 fotogramas por segundo, suficiente para detectar objetos relativamente est\u00e1ticos en una inspecci\u00f3n a\u00e9rea.<\/p>\n\n\n\n<p>El modelo elegido fue <strong>yolov8m<\/strong> (medium) en lugar del nano original: tres veces m\u00e1s par\u00e1metros, notablemente mejor en objetos peque\u00f1os a distancia, que es el caso de uso habitual viendo el terreno desde 50-100 metros de altura. El umbral de confianza se fij\u00f3 en <strong>0.4<\/strong>, m\u00e1s permisivo que el 0.6 inicial, asumiendo que en inspecci\u00f3n de infraestructuras es preferible revisar alg\u00fan falso positivo antes que perder un hallazgo real.<\/p>\n\n\n\n<p>La imagen Docker del procesador pas\u00f3 por una optimizaci\u00f3n relevante: la versi\u00f3n inicial inclu\u00eda PyTorch con soporte CUDA completo, que ocupa 9,6 GB. Como el servidor no tiene GPU, se sustituy\u00f3 por la versi\u00f3n CPU-only, reduciendo la imagen de <strong>9,6 GB a 3 GB<\/strong>. Un ahorro de 6,5 GB que importa cuando el disco ra\u00edz de la VM tiene 38 GB.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Re-an\u00e1lisis de v\u00eddeos grabados: una funcionalidad que surgi\u00f3 sola<\/h2>\n\n\n\n<p>Durante el desarrollo surgi\u00f3 una funcionalidad que no estaba en el planteamiento inicial pero que tiene mucho sentido: la posibilidad de re-analizar a posteriori los v\u00eddeos grabados por MediaMTX. El caso de uso es directo: si despu\u00e9s de un vuelo se quiere aplicar un modelo diferente, bajar el umbral de confianza, o simplemente revisar un vuelo anterior con mayor detalle, no hace falta volver a volar. El servidor tiene grabado el v\u00eddeo completo.<\/p>\n\n\n\n<p>El endpoint <code>POST \/audit\/flights\/{id}\/reanalyze<\/code> acepta opcionalmente un umbral de confianza distinto al por defecto, lanza el re-an\u00e1lisis en background y devuelve un <code>job_id<\/code> para consultar el estado. La l\u00f3gica de inferencia se refactoriz\u00f3 en un m\u00f3dulo compartido (<code>inference.py<\/code>) entre el procesado en tiempo real y el re-an\u00e1lisis de ficheros.<\/p>\n\n\n\n<p>Aqu\u00ed apareci\u00f3 un <em>bug<\/em> interesante: los segmentos MP4 grabados por MediaMTX contienen frames H.264 corruptos intercalados, provocando que <code>cv2.VideoCapture.read()<\/code> falle en aproximadamente la mitad de las lecturas. El c\u00f3digo original hac\u00eda <code>break<\/code> en el primer fallo, procesando en la pr\u00e1ctica solo el primer frame del v\u00eddeo. La correcci\u00f3n fue saltar los frames fallidos y detener el procesado \u00fanicamente cuando hay m\u00e1s de 50 fallos consecutivos, que indica el final real del fichero.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PostGIS: la georreferenciaci\u00f3n en una consulta<\/h2>\n\n\n\n<p>La base de datos espacial es el n\u00facleo que une el procesado de v\u00eddeo con la cartograf\u00eda. Las cuatro tablas a\u00f1adidas usan tipos <code>GEOMETRY<\/code> nativos de PostGIS con \u00edndices espaciales GIST, lo que permite consultas de proximidad geogr\u00e1fica y temporal eficientes incluso con miles de puntos de telemetr\u00eda por vuelo.<\/p>\n\n\n\n<p>La georreferenciaci\u00f3n de una detecci\u00f3n se reduce a esto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT ST_X(geom::geometry) AS lon,\n       ST_Y(geom::geometry) AS lat\nFROM drone_telemetry\nWHERE flight_id = :flight_id\nORDER BY ABS(timestamp_ms - :detection_timestamp)\nLIMIT 1<\/code><\/pre>\n\n\n\n<p>Una sola consulta que encuentra el punto GPS m\u00e1s cercano en tiempo al momento de la detecci\u00f3n. Sencillo, pero correcto: el \u00edndice sobre <code>timestamp_ms<\/code> garantiza que sea r\u00e1pido, y la l\u00f3gica de sincronizaci\u00f3n por timestamp de la app garantiza que la coordenada resultante sea geogr\u00e1ficamente precisa con independencia de la latencia de red.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">El visor: hallazgos IA sobre el ortomosaico<\/h2>\n\n\n\n<p>El resultado final es accesible desde el navegador en <code>\/audit\/view\/{flight_id}<\/code>. El visor Leaflet superpone dos capas: el ortomosaico GeoTIFF generado por ODM, cargado directamente en el navegador v\u00eda <code>georaster-layer-for-leaflet<\/code> sin necesidad de un servidor de <em>tiles<\/em>, y los hallazgos de IA como marcadores GeoJSON coloreados por confianza (rojo por encima del 85%, naranja el resto). Cada marcador abre un <em>popup<\/em> con clase detectada, porcentaje de confianza, timestamp y miniatura del frame anotado. El visor funciona tambi\u00e9n sin ortomosaico, mostrando los marcadores sobre OpenStreetMap mientras el procesado ODM todav\u00eda est\u00e1 en curso.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"544\" src=\"https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG-20260411-WA0002-1024x544.jpg\" alt=\"\" class=\"wp-image-11747\" srcset=\"https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG-20260411-WA0002-1024x544.jpg 1024w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG-20260411-WA0002-300x159.jpg 300w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG-20260411-WA0002-768x408.jpg 768w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG-20260411-WA0002-1536x816.jpg 1536w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG-20260411-WA0002.jpg 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Capa con el ortomosaico y el resultado del vuelo, as\u00ed como una reproducci\u00f3n del v\u00eddeo transmitido<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Claude Code como integrador de sistemas, de nuevo<\/h2>\n\n\n\n<p>Como en el despliegue del stack ODM base, Claude Code actu\u00f3 aqu\u00ed como ingeniero de sistemas aut\u00f3nomo. El proceso sigui\u00f3 el mismo patr\u00f3n: un prompt detallado con el contexto del entorno existente, los componentes a desplegar en orden y los criterios de \u00e9xito para cada fase, ejecutado directamente en el servidor.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-768x1024.jpg\" alt=\"\" class=\"wp-image-11748\" srcset=\"https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-768x1024.jpg 768w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-225x300.jpg 225w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-1152x1536.jpg 1152w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-1536x2048.jpg 1536w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-1024x1365.jpg 1024w, https:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2026\/04\/IMG_20260410_171916633_HDR-scaled.jpg 1920w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\">D\u00e1ndolo todo con Claude Code<\/figcaption><\/figure>\n\n\n\n<p>La restricci\u00f3n m\u00e1s importante que se impuso fue no tocar nada del <em>stack<\/em> existente. El <em>prompt<\/em> lo dec\u00eda expl\u00edcitamente, y la verificaci\u00f3n final lo comprob\u00f3 uno a uno: todos los servicios ODM preexistentes en el estado exacto en que estaban antes del despliegue, con sus datos intactos. La \u00fanica modificaci\u00f3n al stack original fue la adici\u00f3n de tres bloques <code>location<\/code> en <code>nginx.conf<\/code>.<\/p>\n\n\n\n<p>Lo que resulta cada vez m\u00e1s evidente con el uso es que Claude Code no es solo una herramienta para generar c\u00f3digo: es capaz de razonar sobre un sistema complejo existente, identificar los puntos de integraci\u00f3n correctos y tomar decisiones coherentes con la arquitectura preexistente. La decisi\u00f3n de reutilizar la base de datos PostgreSQL existente a\u00f1adiendo tablas nuevas en lugar de crear un contenedor separado, o la de usar el script DDL idempotente para que pueda re-ejecutarse sin riesgo, son el tipo de decisiones que toma alguien que entiende el sistema, no alguien que ejecuta instrucciones literalmente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lo que viene<\/h2>\n\n\n\n<p>Con este m\u00f3dulo desplegado, el servidor ofrece ya las dos capacidades del sistema completo: fotogrametr\u00eda diferida con ODM y auditor\u00eda en tiempo real con YOLOv8. Lo que queda pendiente es conectar ambas desde la app Android: que la app inicie autom\u00e1ticamente el stream RTMP al comenzar una misi\u00f3n, env\u00ede la telemetr\u00eda al m\u00f3dulo de auditor\u00eda, y muestre las alertas de detecci\u00f3n en la pantalla del operador durante el vuelo. Eso es el contenido de la Fase 5 de la <em>app<\/em>, pero eso quedar\u00e1 para un siguiente art\u00edculo de la serie.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">Esta entrada es la parte 7 de 7 de la serie <a href=\"https:\/\/bitacora.eniac2000.com\/?series=fotogrametria-asistida-por-ia\" class=\"series-1957\" title=\"Fotogrametr\u00eda asistida por IA\">Fotogrametr\u00eda asistida por IA<\/a><\/div><p>Cuando empec\u00e9 esta serie de art\u00edculos, el objetivo era construir<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1845,13],"tags":[1959,537,540,551,688,1965,811,824,1966,1202,1964],"series":[1957],"class_list":["post-11744","post","type-post","status-publish","format-standard","hentry","category-generado-con-ia","category-informatica","tag-claude-code","tag-dji-mini-3-pro","tag-docker","tag-dron","tag-fotogrametria","tag-geojson","tag-hp-dl360p-gen8","tag-ia","tag-leaflet","tag-open-drone-map","tag-yolo","series-fotogrametria-asistida-por-ia"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts\/11744","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11744"}],"version-history":[{"count":1,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts\/11744\/revisions"}],"predecessor-version":[{"id":11749,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts\/11744\/revisions\/11749"}],"wp:attachment":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11744"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=11744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}