OpenCV STM32F7-Discovery-l

OpenCV STM32F7-Discovery-l Olen ĂŒks operatsioonisĂŒsteemi arendajatest Embox, ja selles artiklis rÀÀkisin sellest, kuidas suutsin OpenCV-d STM32746G plaadil kĂ€ivitada.

Kui otsingumootorisse sisestada midagi sellist nagu «OpenCV on STM32 board», siis leiab ĂŒsna palju inimesi, kes on huvitatud selle biblioteka kasutamisest STM32 plaatidel vĂ”i teistel mikroprotsessoritel.
On mitmeid videoid, mis pealkirja pÔhjal peaksid demonstreerima seda, mida on vaja, kuid tavaliselt (kÔigis videot, mida olen nÀinud) on STM32 plaadil tehtud ainult pildi saamine kaamerast ja tulemuse kuvamine ekraanil, samas kui pildi töötlemine toimus kas tavalises arvutis vÔi vÔimsamatel plaatidel (nÀiteks Raspberry Pi).

Miks see on keeruline?

OtsingupÀringute populaarsus on tingitud sellest, et OpenCV on kÔige populaarsem arvutinÀgemise teek, seega on paljud arendajad selle eest tuttavad, ja vÔimalus kÀivitada lauaarvutiks mÔeldud kood mikroprotsessoril lihtsustab arendamisprotsessi. Kuid miks ei ole siiani populaarseid lahenduste retsepte selle probleemi lahendamiseks?

OpenCV kasutamise probleem vÀiksematel plaatidel on seotud kahe omadusega:

  • Kui teegi isegi minimaalse moodulite kogumiga kokku panna, siis STM32F7Discovery vĂ€lkmĂ€lusse lihtsalt ei mahu (isegi ilma operatsioonisĂŒsteemita) vĂ€ga suure koodi tĂ”ttu (mitu megabaidi instruktsioone)
  • Ise teek on kirjutatud C++-s, seega
    • On vajalik C++ jooksuta teatamine (erandid jne)
    • VĂ€he LibC/Posix toe, mis tavaliselt on integreeritud sĂŒsteemide opsĂŒsteemidesse — on vajalik C++ standardraamatukogu ja STL malliraamatukogu (vector jne)

Portimine Emboxi

Nagu tavaliselt, enne kui porteerite mĂ”nda programmide opsĂŒsteemi, on hea proovida see koguda sellisel kujul, nagu arendajad selle ette nĂ€gid. Meie juhul ei ole sellega probleeme — algkoodid on saadaval GitHubis, teeki saab GNU/Linux'is tavalise cmake abil kokku panna.

Headest uudistest — OpenCV-d saab otse vĂ€ljaĂ”ppe kaudu kokku panna staatilise teegina, mis muudab portimise lihtsamaks. Kogume teegi standardse config-iga ja vaatame, palju ruumi nad kasutavad. Iga moodul kogutakse eraldi teegina.

> size lib/*so --totals
   text    data     bss     dec     hex filename
1945822   15431     960 1962213  1df0e5 lib/libopencv_calib3d.so
17081885     170312   25640 17277837    107a38d lib/libopencv_core.so
10928229     137640   20192 11086061     a928ed lib/libopencv_dnn.so
 842311   25680    1968  869959   d4647 lib/libopencv_features2d.so
 423660    8552     184  432396   6990c lib/libopencv_flann.so
8034733   54872    1416 8091021  7b758d lib/libopencv_gapi.so
  90741    3452     304   94497   17121 lib/libopencv_highgui.so
6338414   53152     968 6392534  618ad6 lib/libopencv_imgcodecs.so
21323564     155912  652056 22131532    151b34c lib/libopencv_imgproc.so
 724323   12176     376  736875   b3e6b lib/libopencv_ml.so
 429036    6864     464  436364   6a88c lib/libopencv_objdetect.so
6866973   50176    1064 6918213  699045 lib/libopencv_photo.so
 698531   13640     160  712331   ade8b lib/libopencv_stitching.so
 466295    6688     168  473151   7383f lib/libopencv_video.so
 315858    6972   11576  334406   51a46 lib/libopencv_videoio.so
76510375     721519  717496 77949390    4a569ce (TOTALS)

Viimane rida nÀitab, et .bss ja .data ei vÔta palju ruumi, kuid koodi on enam kui 70 MiB. On selge, et kui see staatiliselt kindla rakendusega siduda, siis koodi maht vÀheneb.

Proovime eemaldada vÔimalikult palju mooduleid, et koostada minimaalne nÀide (mis nÀiteks lihtsalt kuvab OpenCV versiooni), nii et vaatame. cmake .. -LA ja blokeerime kÔik valikutes, mida on vÔimalik blokeerida.

        -DBUILD_opencv_java_bindings_generator=OFF 
        -DBUILD_opencv_stitching=OFF 
        -DWITH_PROTOBUF=OFF 
        -DWITH_PTHREADS_PF=OFF 
        -DWITH_QUIRC=OFF 
        -DWITH_TIFF=OFF 
        -DWITH_V4L=OFF 
        -DWITH_VTK=OFF 
        -DWITH_WEBP=OFF

> size lib/libopencv_core.a --totals
   text    data     bss     dec     hex filename
3317069   36425   17987 3371481  3371d9 (TOTALS)

Ühelt poolt, see on ainult ĂŒks teegi moodul, teiselt poolt, see pole koodi suuruse optimeerimise tĂ”ttu (-Os). ~3 MiB koodi – see on ikka veel piisavalt palju, kuid annab juba lootust edule.

KĂ€ivitamine emulaatoris

Emulaatoris on lihtsam siluda, seega veendume kÔigepealt, et teek töötab qemu-s. Emuleeritud platvormiks valisin Integrator/CP, kuna esiteks on see samuti ARM ja teiseks toetab Embox selle platvormi jaoks graafika vÀljundit.

Emboxil on mehhanism vÀliste teekide kompileerimiseks, millega lisame OpenCV moodulina (edastades kÔik samad valikud «minimaalse» töötlemise jaoks staatiliste teekidena), pÀrast seda lisan kÔige lihtsama rakenduse, mis nÀeb vÀlja jÀrgmiselt:

version.cpp:

#include 
#include 

int main() {
    printf("OpenCV: %s", cv::getBuildInformation().c_str());

    return 0;
}

Kompileerime sĂŒsteemi, kĂ€ivitame – saame oodatud vĂ€ljundi.

root@embox: /#opencv_version                                                     
OpenCV: 
Üldine konfiguratsioon OpenCV 4.0.1 =====================================
  Versioonikontroll:               bd6927bdf-dirty

  Platvorm:
    Aeg:                          2019-06-21T10:02:18Z
    Host:                        Linux 5.1.7-arch1-1-ARCH x86_64
    Sihitarget:                  Üldine arm-unknown-none
    CMake:                       3.14.5
    CMake generaator:            Unix Makefiles
    CMake ehitusvahend:         /usr/bin/make
    Konfiguratsioon:             Debug

  CPU/HW omadused:
    Alus:
      nÔutud:                    DETECT
      keelatud:                  VFPV3 NEON

  C/C++:
    Ehitatud dĂŒnaamilisteks teekideks?:      EI

Edasi on teised kogumise parameetrid - milliste lippudega see kompileeritud on, millised OpenCV moodulid on kogumisse kaasatud jne.

JÀrgmine samm on kÀivitada mÔni nÀidis, parem oleks mÔni standardne, mida arendajad ise pakuvad. oma veebilehel. Ma valisin Canny servade detektori.

NĂ€idis tuli natuke ĂŒmber kirjutada, et tulemus otse frame bufferisse kuvada. Seda tuli teha, kuna funktsioon imshow() oskab pilte kuvada QT, GTK ja Windowsi liideste kaudu, mida STM32 seadistuses kindlasti ei ole. Tegelikult saab QT-d ka STM32F7Discovery-l kĂ€ivitada, aga sellest rÀÀgitakse juba teises artiklis 🙂

PĂ€rast lĂŒhikest arutelu, millises formaadis servade detektori töö tulemus hoitakse, saame pildi.

OpenCV STM32F7-Discovery-l

Originaalpilt

OpenCV STM32F7-Discovery-l

Tulemus

KĂ€ivitus STM32F7Discovery-l

32F746GDISCOVERY-l on mitu mÀlusegmenti, mida saame erinevalt kasutada

  1. 320KiB jÀrgnevat mÀlu
  2. 1MiB vÀlkmÀlu pildifaili jaoks
  3. 8MiB SDRAM
  4. 16MiB QSPI NAND vÀlkmÀlukaart
  5. microSD mÀlukaardi pesad

SD-kaarti saab kasutada piltide salvestamiseks, kuid minimaalse nÀidise kÀitamise kontekstis ei ole see eriti kasulik.
Ekraanil on eraldusvĂ”ime 480×272, seega frame bufferi mĂ€lu suurus on 522 240 baiti 32-bitise sĂŒgavusega, st see on suurem kui operatiivmĂ€lu suurus, seega frame buffer ja hunnik (mis on vajalik ka OpenCV jaoks, et hoida andmeid piltide ja abistruktuuride jaoks) asub SDRAM-is, kĂ”ik muu (mĂ€lu stekkide ja muude sĂŒsteemivajaduste jaoks) saadetakse RAM-i.

Kui vÔtta STM32F7Discovery minimaalne konfiguratsioon (kÔik vÔrgud vÀlja visata, kÔik kÀsud, stekke vÔimalikult vÀikesteks teha jne) ja lisada sinna OpenCV koos nÀidistega, on nÔutav mÀlu jÀrgmine:

   text    data     bss     dec     hex filename
2876890  459208  312736 3648834  37ad42 build/base/bin/embox

Nende jaoks, kes ei ole eriti tuttavad sellega, kuhu sektsioonid paigutatakse, selgitan: .text ja .rodata sisaldavad juhiseid ja konstande (lihtsalt öeldes, readonly-andmeid), .data sisaldavad muudetavaid andmeid, .bss sisaldab nullitud muutujaid, millele tuleb siiski koht anda (see sektsioon "lÀheb" RAM-i).

Hea uudis on see, et .data/.bss peavad mahutama, aga probleem on selles, et .text ruumi on ainult 1MiB. NĂ€iteks saab nĂ€idisekraanist pildi eemaldada ja lugeda seda SD-kaardilt mĂ€llu kĂ€ivitamisel, aga fruits.png kaalub umbes 330KiB, nii et see probleem ei lahenda: suurem osa .text koostis on tĂ”epoolest OpenCV kood. .text PĂ”himĂ”tteliselt jÀÀb ĂŒle vaid ĂŒks — laadida koodi osa QSPI-mĂ€lupulgale (sel on spetsiaalne tööreĆŸiim, mis vĂ”imaldab mĂ€lu sĂŒsteembussile kaardistada, mistĂ”ttu protsessor saab neile andmetele otse juurde pÀÀseda). Kuid on ĂŒks probleem: esiteks, QSPI-mĂ€lupulga mĂ€lu ei ole kohe pĂ€rast seadme taaskĂ€ivitamist saadaval (moodul tuleb eraldi initsialiseerida), teiseks ei saa seda mĂ€lupulka tavalise laadijaga "vĂ€lja kirjutada".

LÔpuks otsustati siduda kogu kood QSPI-sse ja kirjutada selle peale kohandatud laadija, mis saab vajaliku binaari TFTP kaudu.

Idee portida see teek Emboxile tekkis umbes aasta tagasi, kuid see lĂŒkati korduvalt edasi erinevatel pĂ”hjustel. Üks neist on libstdc++ ja standardne malliraamatukogu toetus. C++ toetuse probleem Emboxis jÀÀb sellest artiklist vĂ€ljapoole, seega ĂŒtlen vaid, et meil Ă”nnestus saavutada vajaliku mahuga toetus selle teegi jaoks 🙂

Tulemus

LĂ”ppkokkuvĂ”ttes need probleemid ĂŒletati (vĂ€hemalt piisavas ulatuses OpenCV nĂ€idise tööks) ja nĂ€idis kĂ€ivitus. 40 pikka sekundit vĂ”tab arvel servade leidmine Canny filtriga. See on muidugi liiga pikk (on mĂ”tteid, kuidas seda optimeerida, sellest vĂ”iks kirjutada eraldi artikli juhul, kui see Ă”nnestub).

Siiski oli vahe-eesmĂ€rk luua prototĂŒĂŒp, mis nĂ€itab pĂ”himĂ”ttelist vĂ”imalust kĂ€ivitada OpenCV STM32-l, seega see eesmĂ€rk saavutati, hurraa!

OpenCV STM32F7-Discovery-l

tl;dr: samm-sammuline juhend

0: Laadige Emboxi allikakoodid alla, nÀiteks nii:

git clone https://github.com/embox/embox && cd ./embox

    1: Alustame laadija kogumisega, mis "vÀlja kirjutab" QSPI mÀlupulga.

make confload-arm/stm32f7cube

    tee confload-arm/stm32f7cube

NĂŒĂŒd tuleb seadistada vĂ”rk, kuna me laadime kujutise TFTP kaudu. IP-aadresside seadmiseks plaadil ja hostil tuleb muuta faili conf/rootfs/network.

Konfiguratsiooni nÀidis:

iface eth0 inet static
    address 192.168.2.2
    netmask 255.255.255.0
    gateway 192.168.2.1
    hwaddress aa:bb:cc:dd:ee:02

vĂ€rav — hosti aadress, kust kuvandi laadimine toimub, aadress — seadme aadress.

PÀrast seda kogume kÀivitaja:

    tee

2: Tavaline kĂ€ivitaja laadimine seadmele (palun vabandage mĂ€ngu sĂ”na) — siin pole midagi spetsiifilist, seda tuleb teha nagu iga teise rakenduse puhul STM32F7Discovery jaoks. Kui te ei tea, kuidas seda teha, saate lugeda sellest siit.
3: Kujutise kompileerimine OpenCV konfiguratsiooniga.

    make confload-platform/opencv/stm32f7discovery
    make

4: ELF sektsioonide eraldamine, mis tuleb kirjutada QSPI-sse, faili qspi.bin

    arm-none-eabi-objcopy -O binary build/base/bin/embox build/base/bin/qspi.bin 
        --only-section=.text --only-section=.rodata 
        --only-section='.ARM.ex*' 
        --only-section=.data

Kaustas conf on skript, mis seda teeb, seega on vÔimalik see kÀivitada

    ./conf/qspi_objcopy.sh # Vajalik binarne fail -- build/base/bin/qspi.bin

5: TFTP abil laadime qspi.bin.bin QSPI-mÀlupulgale. Hostis tuleb qspi.bin kopeerida tftp-serveri juurkaustasse (tavaliselt on see /srv/tftp/ vÔi /var/lib/tftpboot/; vastava serveri paketid on enamiku populaarsete distributsioonide jaoks olemas, tavaliselt nimetatakse tftpd vÔi tftp-hpa, mÔnikord tuleb teha systemctl start tftpd.service selle kÀivitamiseks).

    # ĐČĐ°Ń€ĐžĐ°ĐœŃ‚ ĐŽĐ»Ń tftpd
    sudo cp build/base/bin/qspi.bin /srv/tftp
    # ĐČĐ°Ń€ĐžĐ°ĐœŃ‚ ĐŽĐ»Ń tftp-hpa
    sudo cp build/base/bin/qspi.bin /var/lib/tftpboot

Emboxis (st. kÀivitajas) tuleb sisestada selline kÀsk (eeldades, et serveri aadress on 192.168.2.1):

    embox> qspi_loader qspi.bin 192.168.2.1

6: KĂ€sk goto on vajalik, et "hĂŒpata" QSPI-mĂ€lu. Konkreetne asukoht vĂ”ib varieeruda sĂ”ltuvalt sellest, kuidas kujutis linkitakse, seda aadressi saab vaadata kĂ€suga mem 0x90000000 (algusaadress on teise 32-bitise sĂ”na kujutisest); samuti on vajalik seada virna mĂ€rk sĂŒmboliga -s, virna aadress asub aadressil 0x90000000, nĂ€ide:

    embox>mem 0x90000000
    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275
                      ↑           ↑
              see aadress    see  aadress 
                virnast        esimese
                           kÀsu

    embox>goto -i 0x9000c27f -s 0x20023200 # Lipp -i on vajalik, et keelata katkestused sĂŒsteemi initsialiseerimise ajal

7: KĂ€ivitame

    embox> edges 20

ja naudime 40-sekundilist servade otsingu 🙂

Kui midagi lÀheb valesti, kirjutage probleem meie kodule, vÔi embox-devel@googlegroups.com, vÔi kommentaarides siit.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster