OpenCV vietnē STM32F7-Discovery

OpenCV vietnē STM32F7-Discovery Esmu viens no operētājsistēmas izstrādātājiem Embox, un Å”ajā rakstā es runāŔu par to, kā man izdevās palaist OpenCV uz STM32746G plates.

Ja meklētājprogrammā ierakstāt kaut ko lÄ«dzÄ«gu ā€œOpenCV uz STM32 platesā€, jÅ«s varat atrast diezgan daudz cilvēku, kuri ir ieinteresēti izmantot Å”o bibliotēku uz STM32 plates vai citiem mikrokontrolleriem.
Ir vairāki video, kuriem, spriežot pēc nosaukuma, vajadzētu demonstrēt to, kas ir nepiecieÅ”ams, bet parasti (visos videoklipos, kurus es redzēju) uz STM32 dēļa tika saņemts tikai attēls no kameras un rezultāts tika parādÄ«ts ekrānā, un pati attēlu apstrāde tika veikta vai nu uz parastā datora, vai uz jaudÄ«gākām platēm (piemēram, Raspberry Pi).

Kāpēc tas ir grūti?

MeklÄ“Å”anas vaicājumu popularitāte tiek skaidrota ar to, ka OpenCV ir vispopulārākā datora redzes bibliotēka, kas nozÄ«mē, ka ar to ir iepazinuÅ”ies vairāk izstrādātāju, turklāt iespēja palaist darbvirsmai gatavu kodu mikrokontrollerā ievērojami vienkārÅ”o izstrādes procesu. Bet kāpēc joprojām nav populāru gatavu recepÅ”u Ŕīs problēmas risināŔanai?

OpenCV izmantoÅ”anas problēma uz maziem Å”allēm ir saistÄ«ta ar divām funkcijām:

  • Ja apkopojat bibliotēku pat ar minimālu moduļu komplektu, tā vienkārÅ”i neietilps tā paÅ”a STM32F7Discovery zibatmiņā (pat neņemot vērā operētājsistēmu) ļoti liela koda dēļ (vairāki instrukciju megabaiti)
  • Pati bibliotēka ir rakstÄ«ta C++ valodā, kas nozÄ«mē
    • NepiecieÅ”ams atbalsts pozitÄ«vam izpildlaikam (izņēmumi utt.)
    • Neliels atbalsts LibC/Posix, kas parasti ir atrodams iegulto sistēmu operētājsistēmās - jums ir nepiecieÅ”ama standarta plus bibliotēka un standarta STL veidņu bibliotēka (vektors utt.)

PārneŔana uz Embox

Kā parasti, pirms jebkuru programmu pārneÅ”anas uz operētājsistēmu, ieteicams mēģināt to izveidot tādā formā, kādā izstrādātāji to bija iecerējuÅ”i. MÅ«su gadÄ«jumā ar to nav nekādu problēmu - avota kodu var atrast vietnē github, bibliotēka ir veidota zem GNU/Linux ar parasto cmake.

Labā ziņa ir tā, ka OpenCV var izveidot kā statisku bibliotēku, kas atvieglo pārneÅ”anu. Mēs apkopojam bibliotēku ar standarta konfigurāciju un redzam, cik daudz vietas tās aizņem. Katrs modulis ir apkopots atseviŔķā bibliotēkā.

> 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)

Kā redzat no pēdējās rindas, .bss un .data neaizņem daudz vietas, bet kods ir lielāks par 70 MiB. Ir skaidrs, ka, ja tas ir statiski saistīts ar konkrētu lietojumprogrammu, kods kļūs mazāks.

Mēģināsim izmest pēc iespējas vairāk moduļu, lai tiktu samontēts minimāls piemērs (kas, piemēram, vienkārÅ”i izvadÄ«s OpenCV versiju), tāpēc skatāmies cmake .. -LA un izslēdziet opcijās visu, kas izslēdzas.

        -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)

No vienas puses, tas ir tikai viens bibliotēkas modulis, no otras puses, tas ir bez kompilatora optimizācijas koda izmēram (-Os). ~3 MiB koda vēl ir diezgan daudz, bet jau dod cerību uz panākumiem.

Palaist emulatorā

Emulatorā ir daudz vieglāk atkļūdot, tāpēc vispirms pārliecinieties, vai bibliotēka darbojas qemu. Kā emulētu platformu es izvēlējos Integrator / CP, jo pirmkārt, tas ir arÄ« ARM, un, otrkārt, Embox atbalsta grafikas izvadi Å”ai platformai.

Embox ir ārējo bibliotēku veidoÅ”anas mehānisms, izmantojot to, mēs pievienojam OpenCV kā moduli (nododot visas tās paÅ”as opcijas "minimālajai" veidoÅ”anai statisko bibliotēku veidā), pēc tam pievienoju vienkārÅ”u lietojumprogrammu, kas izskatās Ŕādi:

version.cpp:

#include <stdio.h>
#include <opencv2/core/utility.hpp>

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

    return 0;
}

Mēs saliekam sistēmu, palaižam to - mēs iegūstam gaidīto rezultātu.

root@embox:/#opencv_version                                                     
OpenCV: 
General configuration for OpenCV 4.0.1 =====================================
  Version control:               bd6927bdf-dirty

  Platform:
    Timestamp:                   2019-06-21T10:02:18Z
    Host:                        Linux 5.1.7-arch1-1-ARCH x86_64
    Target:                      Generic arm-unknown-none
    CMake:                       3.14.5
    CMake generator:             Unix Makefiles
    CMake build tool:            /usr/bin/make
    Configuration:               Debug

  CPU/HW features:
    Baseline:
      requested:                 DETECT
      disabled:                  VFPV3 NEON

  C/C++:
    Built as dynamic libs?:      NO
< Š”Š°Š»ŃŒŃˆŠµ ŠøŠ“ут ŠæрŠ¾Ń‡ŠøŠµ ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры сŠ±Š¾Ń€ŠŗŠø -- с ŠŗŠ°ŠŗŠøŠ¼Šø фŠ»Š°Š³Š°Š¼Šø ŠŗŠ¾Š¼ŠæŠøŠ»ŠøрŠ¾Š²Š°Š»Š¾ŃŃŒ,
  ŠŗŠ°ŠŗŠøŠµ Š¼Š¾Š“уŠ»Šø OpenCV Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Ń‹ Š² сŠ±Š¾Ń€Šŗу Šø т.Šæ.>

Nākamais solis ir palaist kādu piemēru, vēlams kādu no standarta, ko piedāvā paÅ”i izstrādātāji. jÅ«su vietnē. ES izvēlos robežu detektors gudrs.

Piemērs bija nedaudz jāpārraksta, lai parādÄ«tu attēlu ar rezultātu tieÅ”i kadru buferÄ«. Man tas bija jādara, jo. funkciju imshow() var zÄ«mēt attēlus caur QT, GTK un Windows saskarnēm, kas, protams, noteikti nebÅ«s STM32 konfigurācijā. Faktiski QT var palaist arÄ« STM32F7Discovery, taču tas tiks apspriests citā rakstā šŸ™‚

Pēc īsa precizējuma, kādā formātā tiek saglabāts malu detektora rezultāts, iegūstam attēlu.

OpenCV vietnē STM32F7-Discovery

oriģinālā bilde

OpenCV vietnē STM32F7-Discovery

Piedzīvojiet efektīvu rezultātu spēku

Darbojas ar STM32F7Discovery

Vietnē 32F746GDISCOVERY ir vairākas aparatūras atmiņas sadaļas, kuras mēs varam izmantot vienā vai otrā veidā

  1. 320 KiB RAM
  2. 1 MiB zibspuldze attēlam
  3. 8 MiB SDRAM
  4. 16 MiB QSPI NAND zibspuldze
  5. microSD kartes slots

SD karti var izmantot attēlu glabāŔanai, taču minimāla piemēra darbÄ«bas kontekstā tas nav Ä«paÅ”i noderÄ«gi.
Displeja izŔķirtspēja ir 480Ɨ272, kas nozÄ«mē, ka kadru bufera atmiņa bÅ«s 522 240 baiti 32 bitu dziļumā, t.i. tas ir vairāk nekā RAM lielums, tāpēc kadru buferis un kaudze (kas bÅ«s nepiecieÅ”ama, arÄ« OpenCV, lai saglabātu datus attēliem un palÄ«gstruktÅ«rām) atradÄ«sies SDRAM, viss pārējais (atmiņa stekiem un citām sistēmas vajadzÄ«bām ) pāries uz RAM .

Ja ņemam STM32F7Discovery minimālo konfigurāciju (izmetam visu tÄ«klu, visas komandas, izveidosim pēc iespējas mazākas stekas utt.) un pievienosim tur OpenCV ar piemēriem, vajadzÄ«gā atmiņa bÅ«s Ŕāda:

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

Tiem, kuri nav Ä«paÅ”i pazÄ«stami ar to, kuras sadaļas kurp iet, paskaidroÅ”u: in .text Šø .rodata instrukcijas un konstantes (rupji runājot, tikai lasāmie dati) slēpjas .data dati ir mainÄ«gi, .bss ir "nulled" mainÄ«gie, kuriem tomēr ir nepiecieÅ”ama vieta (Ŕī sadaļa "iet" uz RAM).

Labā ziņa ir tā .data/.bss vajadzētu derēt, bet ar .text problēma ir tā, ka attēlam ir tikai 1 MiB atmiņas. Var izmest .text attēlu no piemēra un palasiet to, piemēram, no SD kartes atmiņā startÄ“Å”anas laikā, bet fruits.png sver aptuveni 330KiB, tāpēc tas neatrisinās problēmu: lielākā daļa .text sastāv no OpenCV koda.

Pa lielam atliek tikai viena lieta - koda daļas ielāde QSPI zibatmiņā (tam ir Ä«paÅ”s darbÄ«bas režīms atmiņas kartÄ“Å”anai sistēmas kopnē, lai procesors varētu tieÅ”i piekļūt Å”iem datiem). Å ajā gadÄ«jumā rodas problēma: pirmkārt, QSPI zibatmiņas diska atmiņa nav pieejama uzreiz pēc ierÄ«ces pārstartÄ“Å”anas (jums ir atseviŔķi jāinicializē atmiņas kartÄ“Å”anas režīms), un, otrkārt, Å”o atmiņu nevar ā€œzibspuldziā€ ar pazÄ«stams bootloader.

Rezultātā tika nolemts saistÄ«t visu kodu QSPI, un flash to ar paÅ”rakstÄ«tu ielādētāju, kas saņems nepiecieÅ”amo bināro, izmantojot TFTP.

Piedzīvojiet efektīvu rezultātu spēku

Ideja Å”o bibliotēku pārnest uz Embox radās aptuveni pirms gada, taču atkal un atkal dažādu iemeslu dēļ tika atlikta. Viens no tiem ir atbalsts libstdc++ un standarta veidņu bibliotēkai. C++ atbalsta problēma Embox ir ārpus Ŕī raksta darbÄ«bas jomas, tāpēc Å”eit es teikÅ”u tikai to, ka mums izdevās panākt Å”o atbalstu pareizajā apjomā, lai Ŕī bibliotēka darbotos šŸ™‚

Galu galā Ŕīs problēmas tika pārvarētas (vismaz pietiekami, lai OpenCV piemērs darbotos), un piemērs darbojās. Tas aizņem 40 garas sekundes, lai dēlis meklētu robežas, izmantojot filtru Canny. Tas, protams, ir pārāk garÅ” (ir apsvērumi, kā Å”o lietu optimizēt, veiksmes gadÄ«jumā par to varēs uzrakstÄ«t atseviŔķu rakstu).

OpenCV vietnē STM32F7-Discovery

Taču starpmērÄ·is bija izveidot prototipu, kas parādÄ«s principiālu OpenCV darbināŔanas iespēju uz STM32, attiecÄ«gi Å”is mērÄ·is tika sasniegts, urrā!

tl;dr: soli pa solim instrukcijas

0: lejupielādējiet Embox avotus, piemēram:

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

1: Sāksim ar bootloader montāžu, kas "uzliesmo" QSPI zibatmiņu.

    make confload-arm/stm32f7cube

Tagad jums ir jākonfigurē tÄ«kls, jo. Mēs augÅ”upielādēsim attēlu, izmantojot TFTP. Lai iestatÄ«tu plates un resursdatora IP adreses, jārediģē conf/rootfs/network.

Konfigurācijas piemērs:

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

gateway - resursdatora adrese, no kuras tiks ielādēts attēls, address - valdes adrese.

Pēc tam mēs savācam sāknÄ“Å”anas ielādētāju:

    make

2: Parastā bootloader ielāde (atvainojos par vārdu spēli) uz tāfeles - Å”eit nav nekā konkrēta, jums tas jādara tāpat kā jebkurai citai STM32F7Discovery lietojumprogrammai. Ja nezināt, kā to izdarÄ«t, varat izlasÄ«t par to Å”eit.
3: attēla kompilÄ“Å”ana ar OpenCV konfigurāciju.

    make confload-platform/opencv/stm32f7discovery
    make

4: izraksts no ELF sadaļām, kas jāieraksta QSPI uz 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

Conf direktorijā ir skripts, kas to dara, lai jūs varētu to palaist

    ./conf/qspi_objcopy.sh # ŠŃƒŠ¶Š½Ń‹Š¹ Š±ŠøŠ½Š°Ń€Š½ŠøŠŗ -- build/base/bin/qspi.bin

5. Izmantojot tftp, lejupielādējiet qspi.bin.bin QSPI zibatmiņas diskā. Lai to izdarÄ«tu, resursdatorā kopējiet qspi.bin uz tftp servera saknes mapi (parasti /srv/tftp/ vai /var/lib/tftpboot/; atbilstoŔā servera pakotnes ir pieejamas populārākajos izplatÄ«jumos, ko parasti sauc tftpd vai tftp-hpa, dažreiz tas ir jādara systemctl start tftpd.service sākt).

    # Š²Š°Ń€ŠøŠ°Š½Ń‚ Š“Š»Ń tftpd
    sudo cp build/base/bin/qspi.bin /srv/tftp
    # Š²Š°Ń€ŠøŠ°Š½Ń‚ Š“Š»Ń tftp-hpa
    sudo cp build/base/bin/qspi.bin /var/lib/tftpboot

Embox (t.i., sāknÄ“Å”anas ielādētājā) ir jāizpilda Ŕāda komanda (pieņemam, ka servera adrese ir 192.168.2.1):

    embox> qspi_loader qspi.bin 192.168.2.1

6: ar komandu goto jums "jāielec" QSPI atmiņā. Konkrētā vieta mainÄ«sies atkarÄ«bā no tā, kā attēls ir saistÄ«ts, Å”o adresi varat redzēt ar komandu mem 0x90000000 (sākuma adrese iekļaujas attēla otrajā 32 bitu vārdā); jums arÄ« vajadzēs atzÄ«mēt karodziņu -s, kaudzes adrese ir 0x90000000, piemēram:

    embox>mem 0x90000000
    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275
                      ā†‘           ā†‘
              этŠ¾ Š°Š“рŠµŃ    этŠ¾  Š°Š“рŠµŃ 
                стэŠŗŠ°        ŠæŠµŃ€Š²Š¾Š¹
                           ŠøŠ½ŃŃ‚Ń€ŃƒŠŗцŠøŠø

    embox>goto -i 0x9000c27f -s 0x20023200 # Š¤Š»Š°Š³ -i Š½ŃƒŠ¶ŠµŠ½ чтŠ¾Š±Ń‹ Š·Š°ŠæрŠµŃ‚Šøть ŠæрŠµŃ€Ń‹Š²Š°Š½Šøя Š²Š¾ Š²Ń€ŠµŠ¼Ń ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·Š°Ń†ŠøŠø сŠøстŠµŠ¼Ń‹

    < ŠŠ°Ń‡ŠøŠ½Š°Ń Š¾Ń‚сюŠ“Š° Š±ŃƒŠ“ŠµŃ‚ Š²Ń‹Š²Š¾Š“ Š½Šµ Š·Š°Š³Ń€ŃƒŠ·Ń‡ŠøŠŗŠ°, Š° Š¾Š±Ń€Š°Š·Š° с OpenCV >

7: palaiŔana

    embox> edges 20

un izbaudiet 40 sekunžu robežu meklÄ“Å”anu šŸ™‚

Ja kaut kas noiet greizi - ierakstiet problēmu mÅ«su krātuve, vai uz adresātu sarakstu [e-pasts aizsargāts], vai komentārā Å”eit.

Avots: www.habr.com

Pievieno komentāru