{"id":37914,"date":"2019-10-31T22:20:31","date_gmt":"2019-10-31T19:20:31","guid":{"rendered":"https:\/\/prohoster.info\/blog\/opencv-na-stm32f7-discovery\/"},"modified":"2019-10-31T22:20:31","modified_gmt":"2019-10-31T19:20:31","slug":"opencv-na-stm32f7-discovery","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","title":{"rendered":"OpenCV su STM32F7-Discovery","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenCV su STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a2248ee685ee210ce8f7781435dd1d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/> Sono uno degli sviluppatori del sistema operativo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">Embox<\/a><\/noindex>, e in questo articolo racconter\u00f2 come sono riuscito a far funzionare OpenCV sulla scheda STM32746G.<\/p>\n<p><\/p>\n<p>Cercando su un motore di ricerca qualcosa come &#171;OpenCV su scheda STM32&#187;, si possono trovare molte persone interessate all'uso di questa libreria su schede STM32 o su altri microcontrollori.<br \/>\nCi sono diversi video che, a giudicare dal titolo, dovrebbero dimostrare ci\u00f2 che serve, ma di solito (in tutti i video che ho visto) sulla scheda STM32 veniva effettuata solo l'acquisizione dell'immagine dalla telecamera e la visualizzazione del risultato sullo schermo, mentre il trattamento dell'immagine avveniva o su un comune computer o su schede pi\u00f9 potenti (ad esempio, Raspberry Pi).<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"pochemu-eto-slozhno\">Perch\u00e9 \u00e8 complicato?<\/h1>\n<p><\/p>\n<p>La popolarit\u00e0 delle ricerche \u00e8 dovuta al fatto che OpenCV \u00e8 la libreria di visione artificiale pi\u00f9 popolare, il che significa che pi\u00f9 sviluppatori hanno familiarit\u00e0 con essa, e la possibilit\u00e0 di eseguire codice pronto per desktop su un microcontrollore semplifica notevolmente il processo di sviluppo. Ma perch\u00e9 non ci sono ancora delle ricette pronte e popolari per risolvere questo problema?<\/p>\n<p><\/p>\n<p>Il problema dell'utilizzo di OpenCV su schede di piccole dimensioni \u00e8 legato a due peculiarit\u00e0:<\/p>\n<p><\/p>\n<ul>\n<li>Se si compila la libreria anche con un insieme minimale di moduli, nella memoria flash della stessa STM32F7Discovery semplicemente non ci sta (anche senza considerare il sistema operativo) a causa di un codice molto grande (diversi megabyte di istruzioni)<\/li>\n<li>La libreria stessa \u00e8 scritta in C++, il che significa\n<ul>\n<li>\u00c8 necessaria la supporto del runtime C++ (eccezioni, ecc.)<\/li>\n<li>Poca supporto per LibC\/Posix, che di solito \u00e8 presente nei sistemi operativi per sistemi embedded \u2014 \u00e8 necessaria una libreria standard C++ e una libreria standard di template STL (vector, ecc.)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"portirovanie-na-embox\">Porting su Embox<\/h1>\n<p><\/p>\n<p>Come al solito, prima di portare qualsiasi programma in un sistema operativo \u00e8 meglio provare a compilarlo nella forma in cui \u00e8 stato concepito dagli sviluppatori. Nel nostro caso non ci sono problemi \u2014 il codice sorgente pu\u00f2 essere trovato su <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opencv\/opencv\">GitHub<\/a><\/noindex>, la libreria si compila su GNU\/Linux usando il normale cmake.<\/p>\n<p><\/p>\n<p>Dalle buone notizie \u2014 OpenCV pu\u00f2 essere assemblato come libreria statica, il che rende il porting pi\u00f9 semplice. Compiliamo la libreria con la configurazione standard e vediamo quanto spazio occupano. Ogni modulo viene assemblato in una libreria separata.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">&gt; dimensione lib\/*so --totali\n   testo    dati     bss     dec     esadecimale nomefile\n1945822   15431     960 1962213  1df0e5 lib\/libopencv_calib3d.so\n17081885     170312   25640 17277837    107a38d lib\/libopencv_core.so\n10928229     137640   20192 11086061     a928ed lib\/libopencv_dnn.so\n 842311   25680    1968  869959   d4647 lib\/libopencv_features2d.so\n 423660    8552     184  432396   6990c lib\/libopencv_flann.so\n8034733   54872    1416 8091021  7b758d lib\/libopencv_gapi.so\n  90741    3452     304   94497   17121 lib\/libopencv_highgui.so\n6338414   53152     968 6392534  618ad6 lib\/libopencv_imgcodecs.so\n21323564     155912  652056 22131532    151b34c lib\/libopencv_imgproc.so\n 724323   12176     376  736875   b3e6b lib\/libopencv_ml.so\n 429036    6864     464  436364   6a88c lib\/libopencv_objdetect.so\n6866973   50176    1064 6918213  699045 lib\/libopencv_photo.so\n 698531   13640     160  712331   ade8b lib\/libopencv_stitching.so\n 466295    6688     168  473151   7383f lib\/libopencv_video.so\n 315858    6972   11576  334406   51a46 lib\/libopencv_videoio.so\n76510375     721519  717496 77949390    4a569ce (TOTALE)<\/code><\/pre>\n<p><\/p>\n<p>Come si pu\u00f2 vedere dall'ultima riga, .bss e .data occupano poco spazio, mentre il codice supera i 70 MiB. \u00c8 chiaro che se ci\u00f2 viene collegato staticamente a un'applicazione specifica, il codice diminuir\u00e0.<\/p>\n<p><\/p>\n<p>Cerchiamo di rimuovere quanti pi\u00f9 moduli possibile, in modo da ottenere un esempio minimo (che, ad esempio, semplicemente visualizzer\u00e0 la versione di OpenCV), quindi vediamo. <code>cmake .. -LA<\/code> e disattiviamo tutte le opzioni che possono essere disattivate.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">        -DBUILD_opencv_java_bindings_generator=OFF \n        -DBUILD_opencv_stitching=OFF \n        -DWITH_PROTOBUF=OFF \n        -DWITH_PTHREADS_PF=OFF \n        -DWITH_QUIRC=OFF \n        -DWITH_TIFF=OFF \n        -DWITH_V4L=OFF \n        -DWITH_VTK=OFF \n        -DWITH_WEBP=OFF<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">&gt; dimensione lib\/libopencv_core.a --totali\n   testo    dati     bss     dec     esadecimale nomefile\n3317069   36425   17987 3371481  3371d9 (TOTALE)<\/code><\/pre>\n<p><\/p>\n<p>Da un lato, questo \u00e8 solo un modulo della libreria, dall'altro \u00e8 senza ottimizzazione del compilatore per la dimensione del codice (<code>-Os<\/code>). ~3 MiB di codice \u00e8 comunque piuttosto tanto, ma offre gi\u00e0 speranza di successo.<\/p>\n<p><\/p>\n<h2 id=\"zapusk-v-emulyatore\">Esecuzione in emulatore<\/h2>\n<p><\/p>\n<p>\u00c8 molto pi\u00f9 semplice eseguire il debug in un emulatore, quindi prima ci assicuriamo che la libreria funzioni su qemu. Come piattaforma emulata ho scelto Integrator\/CP, perch\u00e9, da un lato, \u00e8 anch'essa ARM, e dall'altro, Embox supporta l'output grafico per questa piattaforma.<\/p>\n<p><\/p>\n<p>In Embox c'\u00e8 un meccanismo per la compilazione di librerie esterne, con esso aggiungiamo OpenCV come modulo (passando tutte le stesse opzioni per una compilazione &#171;minimale&#187; in forma di librerie statiche), dopodich\u00e9 aggiungo una semplice applicazione, che appare cos\u00ec:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">version.cpp:\n\n#include \n#include \n\nint main() {\n    printf(\"OpenCV: %s\", cv::getBuildInformation().c_str());\n\n    return 0;\n}<\/code><\/pre>\n<p><\/p>\n<p>Compiliamo il sistema, lo avviamo e otteniamo l'output previsto.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">root@embox: \/#opencv_version                                                     \nOpenCV: \nConfigurazione generale per OpenCV 4.0.1 =====================================\n  Controllo versione:               bd6927bdf-dirty\n\n  Piattaforma:\n    Timestamp:                   2019-06-21T10:02:18Z\n    Host:                        Linux 5.1.7-arch1-1-ARCH x86_64\n    Target:                      Generic arm-unknown-none\n    CMake:                       3.14.5\n    Generatore CMake:             Unix Makefiles\n    Strumento di build CMake:     \/usr\/bin\/make\n    Configurazione:               Debug\n\n  Caratteristiche CPU\/HW:\n    Baseline:\n      richiesto:                 DETECT\n      disabilitato:              VFPV3 NEON\n\n  C\/C++:\n    Costruito come librerie dinamiche?:      NO\n&lt; \u0414\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0443\u0442 \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0431\u043e\u0440\u043a\u0438 -- \u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u0444\u043b\u0430\u0433\u0430\u043c\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c,\n  \u043a\u0430\u043a\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 OpenCV \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u0442.\u043f.&gt;<\/code><\/pre>\n<p><\/p>\n<p>Il passo successivo \u00e8 eseguire un esempio, preferibilmente uno degli standard proposti dagli stessi sviluppatori <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/examples.html\">sul loro sito<\/a><\/noindex>. Ho scelto <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/d6\/d56\/samples_2cpp_2edge_8cpp-example.html\">il rilevatore di bordi Canny<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Ho dovuto modificare leggermente l'esempio per visualizzare l'immagine con il risultato direttamente nel framebuffer. Questo \u00e8 stato necessario perch\u00e9 la funzione <code>imshow()<\/code> pu\u00f2 visualizzare immagini tramite le interfacce QT, GTK e Windows, che naturalmente non ci saranno nella configurazione per STM32. In realt\u00e0, QT pu\u00f2 anche essere eseguito su STM32F7Discovery, ma di questo parleremo in un altro articolo \ud83d\ude42<\/p>\n<p><\/p>\n<p>Dopo aver scoperto rapidamente in quale formato viene memorizzato il risultato del rilevatore di bordi, otteniamo l'immagine.<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV su STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/127f90ad8008340d73feb6ece02e52b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>L'immagine originale<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV su STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/da34b3ac2561ae9f223acc5c4fe2a597.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Risultato<\/em><\/p>\n<p><\/p>\n<h2 id=\"zapusk-na-stm32f7discovery\">Esecuzione su STM32F7Discovery<\/h2>\n<p><\/p>\n<p>Su 32F746GDISCOVERY ci sono diverse sezioni di memoria hardware che possiamo utilizzare in vari modi<\/p>\n<p><\/p>\n<ol>\n<li>320KiB di RAM<\/li>\n<li>1MiB di memoria flash per l'immagine<\/li>\n<li>8MiB di SDRAM<\/li>\n<li>16MiB di chiavetta QSPI NAND<\/li>\n<li>Slot per scheda microSD<\/li>\n<\/ol>\n<p><\/p>\n<p>La scheda SD pu\u00f2 essere utilizzata per memorizzare immagini, ma nel contesto dell'esecuzione di un esempio minimo ci\u00f2 non \u00e8 molto utile.<br \/>\nIl display ha una risoluzione di 480&#215;272, il che significa che la memoria necessaria per il frame buffer sar\u00e0 di 522.240 byte con una profondit\u00e0 di 32 bit, cio\u00e8 \u00e8 pi\u00f9 grande della dimensione della memoria RAM, quindi metteremo il frame buffer e l'heap (che sar\u00e0 necessario anche per OpenCV, per memorizzare dati per le immagini e strutture ausiliarie) nella SDRAM, mentre tutto il resto (memoria per stack e altre necessit\u00e0 di sistema) andr\u00e0 nella RAM.<\/p>\n<p><\/p>\n<p>Se prendiamo la configurazione minima per STM32F7Discovery (eliminando tutta la rete, tutti i comandi, riducendo al minimo gli stack, ecc.) e aggiungiamo OpenCV con esempi, la memoria richiesta sar\u00e0 la seguente:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">   text    data     bss     dec     hex filename\n2876890  459208  312736 3648834  37ad42 build\/base\/bin\/embox<\/code><\/pre>\n<p><\/p>\n<p>Per coloro che non sono molto familiari con le sezioni in cui si suddivide il progetto, spiego: in <code>.text<\/code> e <code>.rodata<\/code> si trovano istruzioni e costanti (in termini semplici, dati readonly), in <code>.data<\/code> si trovano dati modificabili, in <code>.bss<\/code> ci sono variabili &#171;nullificate&#187;, che tuttavia necessitano di spazio (questa sezione &#171;andr\u00e0&#187; in RAM).<\/p>\n<p><\/p>\n<p>La buona notizia \u00e8 che <code>.data<\/code>\/<code>.bss<\/code> devono essere memorizzate, ma c'\u00e8 un <code>.text<\/code> problema: sotto l'immagine c'\u00e8 solo 1MiB di memoria. Si pu\u00f2 rimuovere <code>.text<\/code> l'immagine dall'esempio e leggerla, ad esempio, da una scheda SD in memoria all'avvio, ma fruits.png pesa circa 330KiB, quindi questo non risolver\u00e0 il problema: gran parte <code>.text<\/code> \u00e8 composta proprio dal codice di OpenCV.<\/p>\n<p><\/p>\n<p>Fondamentalmente, rimane solo una cosa: caricare parte del codice su una memoria flash QSPI (che ha una modalit\u00e0 di funzionamento speciale per il mapping della memoria sul bus di sistema, cos\u00ec il processore potr\u00e0 accedere direttamente a questi dati). A questo punto sorgono problemi: in primo luogo, la memoria della flash QSPI non \u00e8 accessibile immediatamente dopo il riavvio del dispositivo (deve essere inizializzata separatamente in modalit\u00e0 memory-mapped), in secondo luogo, non \u00e8 possibile &#171;flaggare&#187; questa memoria con un bootloader comune.<\/p>\n<p><\/p>\n<p>Pertanto, \u00e8 stato deciso di linkare tutto il codice nella QSPI e di flasharlo con un bootloader personalizzato, che ricever\u00e0 il binary necessario tramite TFTP.<\/p>\n<p><\/p>\n<h1 id=\"rezultat\">Risultato<\/h1>\n<p><\/p>\n<p>L'idea di portare questa libreria su Embox \u00e8 emersa circa un anno fa, ma di volta in volta \u00e8 stata rimandata per vari motivi. Uno di questi \u00e8 il supporto per libstdc++ e la standard template library. Il problema del supporto C++ in Embox va oltre lo scopo di questo articolo, quindi dir\u00f2 solo che siamo riusciti a ottenere questo supporto nella misura necessaria per il funzionamento di questa libreria \ud83d\ude42<\/p>\n<p><\/p>\n<p>Alla fine, questi problemi sono stati superati (almeno in misura sufficiente per far funzionare l'esempio di OpenCV), e l'esempio \u00e8 stato eseguito. Al microcontrollore servono 40 lunghe secondi per cercare i bordi con il filtro di Canny. \u00c8, ovviamente, troppo tempo (ci sono idee su come ottimizzare questa procedura, di questo si potr\u00e0 scrivere un articolo separato nel caso in cui si ottenga successo). <\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV su STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a400c72865ec17094efc985908914463.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Tuttavia, l'obiettivo intermedio era creare un prototipo che mostrasse la possibilit\u00e0 principe di far funzionare OpenCV su STM32, quindi questo obiettivo \u00e8 stato raggiunto, evviva!<\/p>\n<h4 id=\"tldr-poshagovaya-instrukciya\">tl;dr: istruzioni passo dopo passo<\/h4>\n<p><\/p>\n<p>0: Scarica i sorgenti di Embox, ad esempio in questo modo:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    git clone https:\/\/github.com\/embox\/embox &amp;&amp; cd .\/embox<\/code><\/pre>\n<p><\/p>\n<p>1: Iniziamo a costruire il bootloader che &#171;flasher\u00e0&#187; la memoria flash QSPI.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make confload-arm\/stm32f7cube<\/code><\/pre>\n<p><\/p>\n<p>Ora \u00e8 necessario configurare la rete, poich\u00e9 caricheremo l'immagine tramite TFTP. Per impostare gli indirizzi IP della scheda e dell'host, \u00e8 necessario modificare il file conf\/rootfs\/network.<\/p>\n<p><\/p>\n<p>Esempio di configurazione:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">iface eth0 inet static\n    address 192.168.2.2\n    netmask 255.255.255.0\n    gateway 192.168.2.1\n    hwaddress aa:bb:cc:dd:ee:02<\/code><\/pre>\n<p><\/p>\n<p><code>gateway<\/code> \u2014 l'indirizzo dell'host da cui verr\u00e0 caricata l'immagine, <code>address<\/code> \u2014 l'indirizzo della scheda.<\/p>\n<p><\/p>\n<p>Dopo di che compiliamo il bootloader:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make<\/code><\/pre>\n<p><\/p>\n<p>2: Caricamento normale del bootloader (scusate il gioco di parole) sulla scheda \u2014 non c'\u00e8 nulla di specifico, \u00e8 necessario farlo come per qualsiasi altra applicazione per STM32F7Discovery. Se non sai come farlo, puoi leggere al riguardo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/349034\/\">qui<\/a><\/noindex>.<br \/>\n3: Compilazione dell'immagine con la configurazione per OpenCV.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make confload-platform\/opencv\/stm32f7discovery\n    make<\/code><\/pre>\n<p><\/p>\n<p>4: Estrazione delle sezioni ELF da scrivere in QSPI, in qspi.bin<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    arm-none-eabi-objcopy -O binary build\/base\/bin\/embox build\/base\/bin\/qspi.bin \n        --only-section=.text --only-section=.rodata \n        --only-section='.ARM.ex*' \n        --only-section=.data<\/code><\/pre>\n<p><\/p>\n<p>Nella directory conf si trova uno script che lo fa, quindi puoi eseguirlo<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    .\/conf\/qspi_objcopy.sh # Il binario necessario -- build\/base\/bin\/qspi.bin<\/code><\/pre>\n<p><\/p>\n<p>5: Con tftp carichiamo qspi.bin sul QSPI-flash. Sul host \u00e8 necessario copiare qspi.bin nella cartella principale del server tftp (di solito questa \u00e8 \/srv\/tftp\/ o \/var\/lib\/tftpboot\/; i pacchetti per il server corrispondente sono disponibili nella maggior parte delle distribuzioni popolari, di solito si chiama tftpd o tftp-hpa, a volte \u00e8 necessario fare <code>systemctl start tftpd.service<\/code> per avviarlo).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    # \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f tftpd\n    sudo cp build\/base\/bin\/qspi.bin \/srv\/tftp\n    # \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f tftp-hpa\n    sudo cp build\/base\/bin\/qspi.bin \/var\/lib\/tftpboot<\/code><\/pre>\n<p><\/p>\n<p>Sull'Embox (cio\u00e8 nel bootloader) \u00e8 necessario eseguire questo comando (presumendo che l'indirizzo del server sia 192.168.2.1):<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; qspi_loader qspi.bin 192.168.2.1<\/code><\/pre>\n<p><\/p>\n<p>6: Con il comando <code>goto<\/code> \u00e8 necessario &#171;saltare&#187; nella memoria QSPI. La posizione specifica varier\u00e0 a seconda di come l'immagine viene linkata, questo indirizzo pu\u00f2 essere controllato con un comando <code>mem 0x90000000<\/code> (l'indirizzo di avvio si trova nel secondo word a 32 bit dell'immagine); sar\u00e0 inoltre necessario impostare lo stack con il flag <code>-s<\/code>, l'indirizzo dello stack si trova all'indirizzo 0x90000000, esempio:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt;mem 0x90000000\n    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275\n                      \u2191           \u2191\n              questo \u00e8 l'indirizzo    questo \u00e8 l'indirizzo \n                dello stack        della prima\n                           istruzione\n\n    embox&gt;goto -i 0x9000c27f -s 0x20023200 # Il flag -i \u00e8 necessario per disabilitare le interruzioni durante l'inizializzazione del sistema\n\n    <A><\/code><\/pre>\n<p><\/p>\n<p>7: Avviamo<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; edges 20<\/code><\/pre>\n<p><\/p>\n<p>e godiamoci una ricerca dei bordi di 40 secondi \ud83d\ude42<\/p>\n<p><\/p>\n<p>Se qualcosa non funziona \u2014 scrivi un problema nel <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">nostro repository<\/a><\/noindex>, o nella mailing list embox-devel@googlegroups.com, o nei commenti qui.<\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/457724\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b Embox, \u0438 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c OpenCV \u043d\u0430 \u043f\u043b\u0430\u0442\u0435 STM32746G. \u0415\u0441\u043b\u0438 \u0432\u0431\u0438\u0442\u044c \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 &#171;OpenCV on STM32 board&#187;, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0442\u0435\u0445, \u043a\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 \u043f\u043b\u0430\u0442\u0430\u0445 STM32 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0434\u0435\u043e, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0441\u0443\u0434\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28450,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37914","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47OpenCV \u043d\u0430 STM32F7-Discovery | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:20:31+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:20:31+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47OpenCV su STM32F7-Discovery | ProHoster","description":"Sono uno degli sviluppatori del sistema operativo","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47OpenCV \u043d\u0430 STM32F7-Discovery | ProHoster","og:description":"\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:20:31+00:00","article:modified_time":"2019-10-31T19:20:31+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37914","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 19:45:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:18:22","updated":"2026-01-23 19:45:21","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/37914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=37914"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/37914\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/28450"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=37914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=37914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=37914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}