{"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\/nl\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","title":{"rendered":"OpenCV op STM32F7-Discovery","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenCV op STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a2248ee685ee210ce8f7781435dd1d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/> Ik ben een van de ontwikkelaars van het besturingssysteem <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">Embox<\/a><\/noindex>, en in dit artikel zal ik uitleggen hoe het me gelukt is om OpenCV op de STM32746G ontwikkelplaat te draaien.<\/p>\n<p><\/p>\n<p>Als je iets zoals &#171;OpenCV op STM32 board&#187; in een zoekmachine typt, kun je behoorlijk wat resultaten vinden van mensen die ge\u00efnteresseerd zijn in het gebruik van deze bibliotheek op STM32-borden of andere microcontrollers.<br \/>\nEr zijn verschillende video's die, naar de titel te oordelen, moeten laten zien wat nodig is, maar meestal (in alle video's die ik heb gezien) werd op de STM32 bord alleen de afbeelding van de camera verkregen en het resultaat op het scherm weergeven, terwijl de beeldverwerking ofwel op een gewone computer of op krachtigere borden (bijvoorbeeld Raspberry Pi) plaatsvond.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"pochemu-eto-slozhno\">Waarom is dat moeilijk?<\/h1>\n<p><\/p>\n<p>De populariteit van zoekopdrachten kan worden verklaard door het feit dat OpenCV de meest populaire bibliotheek voor computer vision is, wat betekent dat meer ontwikkelaars ermee bekend zijn, en de mogelijkheid om kant-en-klare desktopcode op een microcontroller uit te voeren, vergemakkelijkt het ontwikkelingsproces aanzienlijk. Maar waarom zijn er tot nu toe geen populaire kant-en-klare recepten voor het oplossen van dit probleem?<\/p>\n<p><\/p>\n<p>Het probleem met het gebruik van OpenCV op kleine borden hangt samen met twee kenmerken:<\/p>\n<p><\/p>\n<ul>\n<li>Zelfs als je de bibliotheek met een minimale set modules compileert, past deze gewoon niet in het flashgeheugen van dezelfde STM32F7Discovery (zelfs zonder het besturingssysteem) vanwege de zeer grote code (enkele megabytes instructies)<\/li>\n<li>De bibliotheek zelf is geschreven in C++, wat betekent\n<ul>\n<li>Dat er ondersteuning voor C++ runtime nodig is (exceptions enz.)<\/li>\n<li>Er is weinig ondersteuning voor LibC\/Posix, die meestal beschikbaar is in besturingssystemen voor embedded systemen \u2014 er is een standaard C++ bibliotheek en een standaard template bibliotheek STL (vector enz.) nodig.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"portirovanie-na-embox\">Porting naar Embox<\/h1>\n<p><\/p>\n<p>Zoals gebruikelijk, is het voor porting van programma's naar een besturingssysteem goed om te proberen deze te compileren in de vorm die de ontwikkelaars voor ogen hadden. In ons geval zijn er geen problemen hiermee \u2014 de source code kan gevonden worden op <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opencv\/opencv\">GitHub<\/a><\/noindex>, de bibliotheek kan worden gebouwd met GNU\/Linux met de gebruikelijke cmake.<\/p>\n<p><\/p>\n<p>Het goede nieuws is dat OpenCV standaard als een statische bibliotheek kan worden gebouwd, wat porting eenvoudiger maakt. We bouwen de bibliotheek met de standaardconfiguratie en kijken hoeveel ruimte ze innemen. Elke module wordt in een aparte bibliotheek gebouwd.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">&gt; size lib\/*so --totals\n   text    data     bss     dec     hex filename\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 (TOTALS)<\/code><\/pre>\n<p><\/p>\n<p>Uit de laatste regel blijkt dat .bss en .data niet veel ruimte innemen, maar de code meer dan 70 MiB is. Het is duidelijk dat als dit statisch met een specifieke applicatie wordt gekoppeld, de code kleiner wordt.<\/p>\n<p><\/p>\n<p>Laten we proberen zoveel mogelijk modules weg te laten om een minimale voorbeeld te cre\u00ebren (dat bijvoorbeeld gewoon de versie van OpenCV weergeeft), dus laten we kijken. <code>cmake .. -LA<\/code> en schakel in de opties alles uit wat uitgeschakeld kan worden.<\/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; size lib\/libopencv_core.a --totals\n   text    data     bss     dec     hex filename\n3317069   36425   17987 3371481  3371d9 (TOTALS)<\/code><\/pre>\n<p><\/p>\n<p>Aan de ene kant is dit slechts \u00e9\u00e9n module van de bibliotheek, aan de andere kant is dit zonder optimalisatie door de compiler op de grootte van de code (<code>-Os<\/code>). ~3 MiB code is nog steeds vrij veel, maar biedt al hoop op succes.<\/p>\n<p><\/p>\n<h2 id=\"zapusk-v-emulyatore\">Uitvoering in een emulator<\/h2>\n<p><\/p>\n<p>Het is veel gemakkelijker om in een emulator te debuggen, dus laten we eerst bevestigen dat de bibliotheek werkt op qemu. Als emulerend platform heb ik Integrator\/CP gekozen, omdat dit ook ARM is en Embox grafische uitvoer voor dit platform ondersteunt.<\/p>\n<p><\/p>\n<p>In Embox is er een mechanisme voor het bouwen van externe bibliotheken. Hiermee voegen we OpenCV toe als module (door dezelfde opties voor de &#171;minimale&#187; build in de vorm van statische bibliotheken door te geven). Daarna voeg ik de eenvoudigste applicatie toe die er als volgt uitziet:<\/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>We bouwen het systeem, starten het op \u2014 en krijgen de verwachte uitvoer.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">root@embox:\\\/\\#opencv_version                                                     \\nOpenCV: \\nAlgemene configuratie voor OpenCV 4.0.1 =====================================\\n  Versiebeheer:               bd6927bdf-dirty\\n\\n  Platform:\\n    Tijdstip:                   2019-06-21T10:02:18Z\\n    Host:                        Linux 5.1.7-arch1-1-ARCH x86_64\\n    Doel:                      Algemeen arm-unknown-none\\n    CMake:                       3.14.5\\n    CMake-generator:             Unix Makefiles\\n    CMake-bouwtool:            \\\/usr\\\/bin\\\/make\\n    Configuratie:               Debug\\n\\n  CPU\\\/HW-functies:\\n    Basislijn:\\n      aangevraagd:                 DETECT\\n      uitgeschakeld:                  VFPV3 NEON\\n\\n  C\\\/C++:\\n    Gebouwd als dynamische libs?:      NEE\\n<\/code><\/pre>\n<p><\/p>\n<p>De volgende stap is om een voorbeeld uit te voeren, bij voorkeur een standaardvoorbeeld dat door de ontwikkelaars zelf wordt aangeboden. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/examples.html\">op hun website.<\/a><\/noindex>. Ik heb gekozen voor <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/d6\/d56\/samples_2cpp_2edge_8cpp-example.html\">de Canny-randdetectie.<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Het voorbeeld moest iets worden herschreven om het resultaat direct in de framebuffer weer te geven. Dit was nodig, aangezien de functie <code>imshow()<\/code> in staat is om afbeeldingen te tekenen via interfaces zoals QT, GTK en Windows, die absoluut niet in de configuratie voor STM32 zullen zitten. In feite kan QT ook worden uitgevoerd op STM32F7Discovery, maar daarover zal in een ander artikel worden gesproken \ud83d\ude42<\/p>\n<p><\/p>\n<p>Na kort te hebben uitgezocht in welk formaat het resultaat van de randdetectie wordt opgeslagen, krijgen we de afbeelding.<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV op STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/127f90ad8008340d73feb6ece02e52b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Oorspronkelijke afbeelding.<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV op STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/da34b3ac2561ae9f223acc5c4fe2a597.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Resultaat<\/em><\/p>\n<p><\/p>\n<h2 id=\"zapusk-na-stm32f7discovery\">Uitvoering op STM32F7Discovery.<\/h2>\n<p><\/p>\n<p>Op de 32F746GDISCOVERY zijn er verschillende hardware-geheugensecties die we op een of andere manier kunnen gebruiken.<\/p>\n<p><\/p>\n<ol>\n<li>320KiB RAM.<\/li>\n<li>1MiB flash-geheugen voor de afbeelding.<\/li>\n<li>8MiB SDRAM.<\/li>\n<li>16MiB QSPI NAND-flash.<\/li>\n<li>Slot voor microSD-kaart.<\/li>\n<\/ol>\n<p><\/p>\n<p>De SD-kaart kan worden gebruikt voor het opslaan van afbeeldingen, maar in de context van het uitvoeren van een minimaal voorbeeld is dit niet erg nuttig.<br \/>\nHet display heeft een resolutie van 480&#215;272, wat betekent dat het geheugen voor de framebuffer 522.240 bytes zal zijn bij een diepte van 32 bit. Dit is meer dan de grootte van het werkgeheugen, dus de framebuffer en de heap (die ook nodig is voor OpenCV, om gegevens voor afbeeldingen en hulpprogramma-structuren op te slaan) zullen in SDRAM worden geplaatst. Alles wat overblijft (geheugen voor stacks en andere systeembehoeften) gaat naar het RAM.<\/p>\n<p><\/p>\n<p>Als we de minimale configuratie voor STM32F7Discovery nemen (alle netwerken, alle commando's verwijderen, de stacks zo klein mogelijk maken, enz.) en daar OpenCV met voorbeelden aan toevoegen, zal het benodigde geheugen als volgt zijn:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">   text    data     bss     dec     hex bestandsnaam\\n2876890  459208  312736 3648834  37ad42 build\\\/base\\\/bin\\\/embox<\/code><\/pre>\n<p><\/p>\n<p>Voor degenen die niet goed bekend zijn met welke secties waarheen gaan, laat me het uitleggen: in <code>.text<\/code> en <code>.rodata<\/code> staan instructies en constanten (grofweg, readonly-gegevens), in <code>.data<\/code> staan veranderlijke gegevens, in <code>.bss<\/code> er liggen &#171;geannuleerde&#187; variabelen die echter ruimte nodig hebben (dit gedeelte &#171;gaat&#187; naar het RAM).<\/p>\n<p><\/p>\n<p>Het goede nieuws is dat <code>.data<\/code>\/<code>.bss<\/code> moeten worden geplaatst, maar het probleem is dat <code>.text<\/code> er slechts 1MiB geheugen voor de afbeelding is. Je kunt de afbeelding uit het voorbeeld verwijderen en deze bijvoorbeeld vanaf een SD-kaart in het geheugen lezen bij het opstarten, maar fruits.png is ongeveer 330KiB, dus dat lost het probleem niet op: het grootste deel <code>.text<\/code> bestaat inderdaad uit OpenCV-code. <code>.text<\/code> Uiteindelijk resteert er nog maar \u00e9\u00e9n optie - een deel van de code op de QSPI-flash op te laden (deze heeft een speciale werkmodus voor geheugenmapping op de systeembus, zodat de processor direct toegang kan krijgen tot deze gegevens). In dit geval ontstaat er een probleem: ten eerste is het geheugen van de QSPI-flash niet onmiddellijk toegankelijk na het opnieuw opstarten van het apparaat (je moet de memory-mapped-modus afzonderlijk initialiseren), en ten tweede kan je dit geheugen niet 'flitsen' met een gebruikelijke bootloader.<\/p>\n<p><\/p>\n<p>Over het algemeen blijft er maar \u00e9\u00e9n ding over \u2014 het laden van een deel van de code naar de QSPI-flash (deze heeft een speciale werkmodus voor het mappen van geheugen naar de systeembus, zodat de processor deze gegevens direct kan aanspreken). Hierbij ontstaat echter een probleem: ten eerste is het QSPI-flashgeheugen niet direct beschikbaar na het opstarten van het apparaat (de memory-mapped modus moet apart worden ge\u00efnitialiseerd), en ten tweede kan dit geheugen niet op de gebruikelijke manier worden &#171;geflashed&#187; met een bootloader.<\/p>\n<p><\/p>\n<p>Het idee om deze bibliotheek naar Embox te porten is ongeveer een jaar geleden ontstaan, maar het werd keer op keer uitgesteld om verschillende redenen. Een daarvan is de ondersteuning van libstdc++ en de standaardtemplatebibliotheek. Het probleem van C++-ondersteuning in Embox valt buiten het bestek van dit artikel, dus ik zal hier alleen zeggen dat we erin geslaagd zijn deze ondersteuning in de benodigde mate voor het functionele gebruik van deze bibliotheek te realiseren \ud83d\ude42<\/p>\n<p><\/p>\n<h1 id=\"rezultat\">Resultaat<\/h1>\n<p><\/p>\n<p>Uiteindelijk werden deze problemen overwonnen (tenminste, in voldoende mate voor het uitvoeren van het OpenCV-voorbeeld), en het voorbeeld werd uitvoerig. Het duurt 40 lange seconden voor de board om de randen met de Canny-filter te vinden. Dit is natuurlijk te lang (er zijn idee\u00ebn om dit te optimaliseren, hierover kan in geval van succes een apart artikel worden geschreven).<\/p>\n<p><\/p>\n<p>Desondanks was de tussenliggende doelstelling het maken van een prototype dat de principi\u00eble mogelijkheid aantoont om OpenCV op STM32 uit te voeren; deze doelstelling is bereikt, hoera! <\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV op STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a400c72865ec17094efc985908914463.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>tl;dr: stap-voor-stap instructies<\/p>\n<h4 id=\"tldr-poshagovaya-instrukciya\">0: Download de Embox-bronbestanden, bijvoorbeeld zo:<\/h4>\n<p><\/p>\n<p>git clone https:\/\/github.com\/embox\/embox &amp;&amp; cd .\/embox<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    1: We beginnen met het bouwen van de bootloader, die de QSPI-flash zal 'flitsen'.<\/code><\/pre>\n<p><\/p>\n<p>1: Laten we beginnen met het bouwen van de bootloader, die de QSPI-flash zal &#171;flaschen&#187;.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    maak confload-arm\/stm32f7cube<\/code><\/pre>\n<p><\/p>\n<p>Je moet nu het netwerk configureren, omdat we de afbeelding via TFTP zullen laden. Om de IP-adressen van de kaart en de host in te stellen, moet je het bestand conf\/rootfs\/network aanpassen.<\/p>\n<p><\/p>\n<p>Voorbeeldconfiguratie:<\/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 het adres van de host waarvan de afbeelding wordt geladen, <code>address<\/code> \u2014 het adres van de kaart.<\/p>\n<p><\/p>\n<p>Daarna bouwen we de bootloader:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make<\/code><\/pre>\n<p><\/p>\n<p>2: Gewone installatie van de bootloader (excuses voor het woordgrapje) op de kaart \u2014 hier is niets speciaals aan, doe dit zoals voor elke andere toepassing voor de STM32F7Discovery. Als je niet weet hoe dit moet, kun je erover lezen <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/349034\/\">here<\/a><\/noindex>.<br \/>\n3: Compileren van de afbeelding met de configuratie voor 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: Extraheren van secties uit ELF, die moeten worden geschreven naar 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>In de directory conf staat een script dat dit doet, dus je kunt het uitvoeren<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    .\/conf\/qspi_objcopy.sh # De benodigde binaire is -- build\/base\/bin\/qspi.bin<\/code><\/pre>\n<p><\/p>\n<p>5: Laad qspi.bin.bin naar de QSPI-flash met tftp. Daartoe moet je qspi.bin naar de rootdirectory van de tftp-server kopi\u00ebren (dit is meestal \/srv\/tftp\/ of \/var\/lib\/tftpboot\/; de pakketten voor de juiste server zijn beschikbaar in de meeste populaire distributies, meestal genaamd tftpd of tftp-hpa, soms is het nodig om <code>systemctl start tftpd.service<\/code> om te starten).<\/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>Op Embox (d.w.z. in de bootloader) moet je het volgende commando uitvoeren (we veronderstellen dat het adres van de server 192.168.2.1 is):<\/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: Met het commando <code>goto<\/code> we moeten &#171;springen&#187; naar het QSPI-geheugen. De exacte locatie zal vari\u00ebren afhankelijk van hoe het beeld is gesimuleerd; dit adres kan worden bekeken met het commando <code>mem 0x90000000<\/code> (het startadres ligt in het tweede 32-bits woord van de afbeelding); je moet ook de stack met het vlaggetje instellen <code>-s<\/code>, het stackadres ligt op het adres 0x90000000, voorbeeld:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt;mem 0x90000000\n    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275\n                      \u2191           \u2191\n              dit is het adres    dit is het adres \n                van de stack        van de eerste\n                           instructie\n\n    embox&gt;goto -i 0x9000c27f -s 0x20023200 # De vlag -i is nodig om onderbrekingen tijdens de systeeminitialisatie te voorkomen<\/code><\/pre>\n<p><\/p>\n<p>7: Start<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; edges 20<\/code><\/pre>\n<p><\/p>\n<p>en geniet van de 40 seconden durende randdetectie \ud83d\ude42<\/p>\n<p><\/p>\n<p>Als er iets misgaat - schrijf dan een issue in <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">onze repository<\/a><\/noindex>, of op de mailinglijst embox-devel@googlegroups.com, of in de opmerkingen hier.<\/p>\n<p>Bron: <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.3 - 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\/nl\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\/nl\/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 op STM32F7-Discovery | ProHoster","description":"Ik ben een van de ontwikkelaars van het besturingssysteem","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\/nl\/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\/nl\/wp-json\/wp\/v2\/posts\/37914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=37914"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/37914\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/28450"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=37914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=37914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=37914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}