OpenCV kwenye STM32F7-Discovery

OpenCV kwenye STM32F7-Discovery Mimi ni mmoja wa watengenezaji wa mfumo wa uendeshaji Embox, na katika makala hii nitazungumzia jinsi nilivyoweza kuendesha OpenCV kwenye bodi ya STM32746G.

Ukiandika kitu kama vile "OpenCV kwenye ubao wa STM32" kwenye injini ya utafutaji, unaweza kupata watu wachache ambao wangependa kutumia maktaba hii kwenye mbao za STM32 au vidhibiti vingine vidogo.
Kuna video kadhaa ambazo, kwa kuzingatia jina, zinapaswa kuonyesha kile kinachohitajika, lakini kawaida (katika video zote ambazo niliona) kwenye ubao wa STM32, picha tu ilipokelewa kutoka kwa kamera na matokeo yalionyeshwa kwenye skrini, na usindikaji wa picha yenyewe ulifanyika ama kwenye kompyuta ya kawaida, au kwenye bodi zenye nguvu zaidi (kwa mfano, Raspberry Pi).

Kwa nini ni ngumu?

Umaarufu wa maswali ya utaftaji unaelezewa na ukweli kwamba OpenCV ndio maktaba maarufu ya maono ya kompyuta, ambayo inamaanisha kuwa watengenezaji wengi wanaifahamu, na uwezo wa kuendesha nambari iliyo tayari ya eneo-kazi kwenye kidhibiti kidogo hurahisisha sana mchakato wa ukuzaji. Lakini kwa nini bado hakuna mapishi maarufu yaliyotengenezwa tayari kwa kutatua shida hii?

Shida ya kutumia OpenCV kwenye shawl ndogo inahusiana na huduma mbili:

  • Ikiwa utakusanya maktaba hata na seti ndogo ya moduli, haitaingia kwenye kumbukumbu ya flash ya STM32F7Discovery sawa (hata bila kuzingatia OS) kwa sababu ya nambari kubwa sana (megabytes kadhaa za maagizo)
  • Maktaba yenyewe imeandikwa katika C ++, ambayo ina maana
    • Unahitaji usaidizi kwa wakati mzuri wa utekelezaji (vighairi, n.k.)
    • Usaidizi mdogo kwa LibC/Posix, ambayo kawaida hupatikana katika OS kwa mifumo iliyopachikwa - unahitaji maktaba ya kawaida ya pamoja na maktaba ya kawaida ya kiolezo cha STL (vekta, n.k.)

Inasafirishwa kwa Embox

Kama kawaida, kabla ya kusambaza programu yoyote kwa mfumo wa uendeshaji, ni wazo nzuri kujaribu kuijenga katika fomu ambayo watengenezaji walikusudia. Kwa upande wetu, hakuna matatizo na hii - msimbo wa chanzo unaweza kupatikana github, maktaba imejengwa chini ya GNU/Linux na cmake ya kawaida.

Habari njema ni kwamba OpenCV inaweza kujengwa kama maktaba tuli nje ya boksi, ambayo hurahisisha uhamishaji. Tunakusanya maktaba iliyo na usanidi wa kawaida na kuona ni nafasi ngapi wanazotumia. Kila moduli inakusanywa katika maktaba tofauti.

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

Kama unavyoona kwenye mstari wa mwisho, .bss na .data hazichukui nafasi nyingi, lakini msimbo ni zaidi ya 70 MiB. Ni wazi kwamba ikiwa hii itaunganishwa kwa takwimu na programu mahususi, msimbo utakuwa mdogo.

Wacha tujaribu kutupa moduli nyingi iwezekanavyo ili mfano mdogo ukusanywe (ambayo, kwa mfano, itatoa toleo la OpenCV), kwa hivyo tunaangalia. cmake .. -LA na kuzima katika chaguzi kila kitu kinachozima.

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

Kwa upande mmoja, hii ni moduli moja tu ya maktaba, kwa upande mwingine, hii ni bila uboreshaji wa mkusanyaji kwa saizi ya nambari (-Os) ~3 MiB ya nambari bado ni nyingi, lakini tayari inatoa tumaini la kufaulu.

Endesha kwenye emulator

Ni rahisi zaidi kutatua hitilafu kwenye emulator, kwa hivyo kwanza hakikisha kwamba maktaba inafanya kazi kwenye qemu. Kama jukwaa lililoigwa, nilichagua Integrator / CP, kwa sababu kwanza, pia ni ARM, na pili, Embox inasaidia pato la picha kwa jukwaa hili.

Embox ina utaratibu wa kujenga maktaba za nje, kwa kuitumia tunaongeza OpenCV kama moduli (kupitisha chaguzi zote sawa za muundo wa "ndogo" katika mfumo wa maktaba tuli), baada ya hapo ninaongeza programu rahisi ambayo inaonekana kama hii:

version.cpp:

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

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

    return 0;
}

Tunakusanya mfumo, kukimbia - tunapata matokeo yanayotarajiwa.

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 Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ Π² сборку ΠΈ Ρ‚.ΠΏ.>

Hatua inayofuata ni kuendesha mfano fulani, ikiwezekana moja ya viwango vya kawaida vinavyotolewa na watengenezaji wenyewe. kwenye tovuti yako. Nilichagua korongo la kugundua mpaka.

Ilibidi mfano uandikwe upya ili kuonyesha picha yenye matokeo moja kwa moja kwenye bafa ya fremu. Ilinibidi kufanya hivi, kwa sababu. kazi imshow() inaweza kuchora picha kupitia miingiliano ya QT, GTK na Windows, ambayo, kwa kweli, haitakuwa kwenye usanidi wa STM32. Kwa kweli, QT pia inaweza kuendeshwa kwenye STM32F7Discovery, lakini hii itajadiliwa katika nakala nyingine πŸ™‚

Baada ya ufafanuzi mfupi ambao muundo wa matokeo ya kizuizi cha makali huhifadhiwa, tunapata picha.

OpenCV kwenye STM32F7-Discovery

picha ya asili

OpenCV kwenye STM32F7-Discovery

Matokeo

Inatumika kwenye Ugunduzi wa STM32F7

Kwenye 32F746GDISCOVERY kuna sehemu kadhaa za kumbukumbu za maunzi ambazo tunaweza kutumia kwa njia moja au nyingine.

  1. RAM ya 320KiB
  2. 1MiB flash kwa picha
  3. 8MiB SDRAM
  4. 16MiB QSPI NAND Flash
  5. yanayopangwa kadi ya microSD

Kadi ya SD inaweza kutumika kuhifadhi picha, lakini katika muktadha wa kuendesha mfano mdogo, hii sio muhimu sana.
Uonyesho una azimio la 480 Γ— 272, ambayo ina maana kwamba kumbukumbu ya framebuffer itakuwa 522 byte kwa kina cha bits 240, i.e. hii ni zaidi ya saizi ya RAM, kwa hivyo fremu na lundo (ambayo itahitajika, pamoja na OpenCV, kuhifadhi data ya picha na miundo ya msaidizi) itapatikana katika SDRAM, kila kitu kingine (kumbukumbu ya rafu na mahitaji mengine ya mfumo. ) itaenda kwa RAM .

Ikiwa tutachukua usanidi wa chini wa STM32F7Discovery (tupa mtandao mzima, amri zote, fanya safu ndogo iwezekanavyo, n.k.) na kuongeza OpenCV na mifano hapo, kumbukumbu inayohitajika itakuwa kama ifuatavyo.

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

Kwa wale ambao hawajui sana ni sehemu gani zinakwenda wapi, nitaelezea: in .text ΠΈ .rodata maagizo na viunga (takriban, data ya kusoma tu) ziko ndani .data data inaweza kubadilika, .bss kuna "nulled" vigezo, ambayo, hata hivyo, haja ya mahali (sehemu hii "itakwenda" kwa RAM).

Habari njema ni hiyo .data/.bss inapaswa kutoshea, lakini na .text shida ni kwamba kuna 1MiB tu ya kumbukumbu kwa picha. Inaweza kutupwa nje .text picha kutoka kwa mfano na kuisoma, kwa mfano, kutoka kwa kadi ya SD hadi kumbukumbu wakati wa kuanza, lakini matunda.png ina uzito wa 330KiB, kwa hivyo hii haitatatua tatizo: wengi .text inajumuisha msimbo wa OpenCV.

Kwa ujumla, kuna jambo moja tu lililobaki - kupakia sehemu ya msimbo kwenye flash ya QSPI (ina hali maalum ya uendeshaji wa ramani ya kumbukumbu kwenye basi ya mfumo, ili processor inaweza kufikia data hii moja kwa moja). Katika kesi hii, shida inatokea: kwanza, kumbukumbu ya gari la QSPI haipatikani mara tu baada ya kifaa kuwashwa tena (unahitaji kuanzisha kando hali iliyopangwa kwa kumbukumbu), na pili, huwezi "kuwasha" kumbukumbu hii na. bootloader inayojulikana.

Kama matokeo, iliamuliwa kuunganisha msimbo wote katika QSPI, na kuiangaza kwa kipakiaji kilichoandikwa kibinafsi ambacho kitapokea binary inayohitajika kupitia TFTP.

Matokeo

Wazo la kupeleka maktaba hii kwa Embox lilionekana takriban mwaka mmoja uliopita, lakini tena na tena liliahirishwa kwa sababu mbalimbali. Mojawapo ni msaada kwa libstdc++ na maktaba ya kiolezo cha kawaida. Shida ya usaidizi wa C ++ katika Embox ni zaidi ya upeo wa nakala hii, kwa hivyo hapa nitasema tu kwamba tumeweza kufikia usaidizi huu kwa kiwango sahihi kwa maktaba hii kufanya kazi πŸ™‚

Mwishowe, matatizo haya yalishindwa (angalau kutosha kwa mfano wa OpenCV kufanya kazi), na mfano ulikimbia. Inachukua sekunde 40 kwa ubao kutafuta mipaka kwa kutumia kichujio cha Canny. Hii, kwa kweli, ni ndefu sana (kuna mazingatio juu ya jinsi ya kuongeza jambo hili, itawezekana kuandika nakala tofauti juu ya hii ikiwa utafanikiwa).

OpenCV kwenye STM32F7-Discovery

Walakini, lengo la kati lilikuwa kuunda mfano ambao utaonyesha uwezekano wa kimsingi wa kuendesha OpenCV kwenye STM32, mtawaliwa, lengo hili lilifikiwa, hooray!

tl; dr: maagizo ya hatua kwa hatua

0: Pakua vyanzo vya Embox, kama hii:

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

1: Hebu tuanze kwa kukusanya bootloader ambayo "itawaka" gari la QSPI flash.

    make confload-arm/stm32f7cube

Sasa unahitaji kusanidi mtandao, kwa sababu. Tutapakia picha kupitia TFTP. Ili kuweka ubao na anwani za IP, unahitaji kuhariri conf/rootfs/network.

Mfano wa usanidi:

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 - anwani ya mwenyeji kutoka ambapo picha itapakiwa, address - anwani ya bodi.

Baada ya hayo, tunakusanya bootloader:

    make

2: Upakiaji wa kawaida wa bootloader (samahani kwa pun) kwenye ubao - hakuna kitu maalum hapa, unahitaji kuifanya kama kwa programu nyingine yoyote ya STM32F7Discovery. Ikiwa hujui jinsi ya kufanya hivyo, unaweza kusoma kuhusu hilo hapa.
3: Kukusanya picha na usanidi wa OpenCV.

    make confload-platform/opencv/stm32f7discovery
    make

4: Dondoo kutoka sehemu za ELF zitaandikwa kwa QSPI hadi 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

Kuna hati kwenye saraka ya conf ambayo hufanya hivi, kwa hivyo unaweza kuiendesha

    ./conf/qspi_objcopy.sh # НуТный Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊ -- build/base/bin/qspi.bin

5: Kwa kutumia tftp, pakua qspi.bin.bin kwenye kiendeshi cha QSPI flash. Kwa seva pangishi, ili kufanya hivyo, nakili qspi.bin kwenye folda ya mizizi ya seva ya tftp (kawaida /srv/tftp/ au /var/lib/tftpboot/; vifurushi vya seva inayolingana vinapatikana katika usambazaji maarufu zaidi, ambao kawaida huitwa. tftpd au tftp-hpa, wakati mwingine lazima ufanye systemctl start tftpd.service kuanza).

    # Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для tftpd
    sudo cp build/base/bin/qspi.bin /srv/tftp
    # Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для tftp-hpa
    sudo cp build/base/bin/qspi.bin /var/lib/tftpboot

Kwenye Embox (i.e. kwenye bootloader), unahitaji kutekeleza amri ifuatayo (tunadhania kuwa seva ina anwani 192.168.2.1):

    embox> qspi_loader qspi.bin 192.168.2.1

6: Kwa amri goto unahitaji "kuruka" kwenye kumbukumbu ya QSPI. Eneo maalum litatofautiana kulingana na jinsi picha inavyounganishwa, unaweza kuona anwani hii kwa amri mem 0x90000000 (anwani ya mwanzo inafaa kwa neno la pili la 32-bit la picha); utahitaji pia kuripoti stack -s, anwani ya rafu iko kwa 0x90000000, kwa mfano:

    embox>mem 0x90000000
    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275
                      ↑           ↑
              это адрСс    это  адрСс 
                стэка        ΠΏΠ΅Ρ€Π²ΠΎΠΉ
                           инструкции

    embox>goto -i 0x9000c27f -s 0x20023200 # Π€Π»Π°Π³ -i Π½ΡƒΠΆΠ΅Π½ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡ€Π΅Ρ‚ΠΈΡ‚ΡŒ прСрывания Π²ΠΎ врСмя ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ систСмы

    < Начиная ΠΎΡ‚ΡΡŽΠ΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π²ΠΎΠ΄ Π½Π΅ Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠ°, Π° ΠΎΠ±Ρ€Π°Π·Π° с OpenCV >

7: Uzinduzi

    embox> edges 20

na ufurahie utafutaji wa mpaka wa sekunde 40 πŸ™‚

Ikiwa kitu kitaenda vibaya - andika suala ndani hazina yetu, au kwa orodha ya wanaopokea barua pepe [barua pepe inalindwa], au kwenye maoni hapa.

Chanzo: mapenzi.com

Kuongeza maoni