OpenCV ar STM32F7-Darganfod

OpenCV ar STM32F7-Darganfod Rwy'n un o ddatblygwyr y system weithredu Embox, ac yn yr erthygl hon byddaf yn siarad am sut y llwyddais i redeg OpenCV ar fwrdd STM32746G.

Os teipiwch rywbeth fel “OpenCV ar fwrdd STM32” i mewn i beiriant chwilio, gallwch ddod o hyd i gryn dipyn o bobl sydd â diddordeb mewn defnyddio'r llyfrgell hon ar fyrddau STM32 neu ficroreolyddion eraill.
Mae yna nifer o fideos a ddylai, o farnu yn ôl yr enw, ddangos yr hyn sydd ei angen, ond fel arfer (yn yr holl fideos a welais) ar y bwrdd STM32, dim ond y ddelwedd a dderbyniwyd o'r camera ac arddangoswyd y canlyniad ar y sgrin, ac roedd y prosesu delweddau ei hun yn cael ei wneud naill ai ar gyfrifiadur rheolaidd, neu ar fyrddau mwy pwerus (er enghraifft, Raspberry Pi).

Pam ei bod hi'n anodd?

Eglurir poblogrwydd ymholiadau chwilio gan y ffaith mai OpenCV yw'r llyfrgell gweledigaeth gyfrifiadurol fwyaf poblogaidd, sy'n golygu bod mwy o ddatblygwyr yn gyfarwydd ag ef, ac mae'r gallu i redeg cod parod bwrdd gwaith ar ficroreolydd yn symleiddio'r broses ddatblygu yn fawr. Ond pam nad oes ryseitiau parod poblogaidd o hyd ar gyfer datrys y broblem hon?

Mae problem defnyddio OpenCV ar siolau bach yn gysylltiedig â dwy nodwedd:

  • Os byddwch chi'n llunio'r llyfrgell hyd yn oed gyda set fach iawn o fodiwlau, ni fydd yn ffitio i mewn i gof fflach yr un STM32F7Discovery (hyd yn oed heb ystyried yr OS) oherwydd cod mawr iawn (sawl megabeit o gyfarwyddiadau)
  • Mae'r llyfrgell ei hun wedi'i hysgrifennu yn C ++, sy'n golygu
    • Angen cefnogaeth ar gyfer amser rhedeg cadarnhaol (eithriadau, ac ati)
    • Ychydig o gefnogaeth i LibC/Posix, a geir fel arfer yn OS ar gyfer systemau wedi'u mewnosod - mae angen llyfrgell safonol plws arnoch a llyfrgell templed STL safonol (fector, ac ati)

Cludo i Embox

Yn ôl yr arfer, cyn trosglwyddo unrhyw raglenni i'r system weithredu, mae'n syniad da ceisio ei adeiladu yn y ffurf y bwriadodd y datblygwyr hynny. Yn ein hachos ni, nid oes unrhyw broblemau gyda hyn - gellir dod o hyd i'r cod ffynhonnell ar github, mae'r llyfrgell wedi'i hadeiladu o dan GNU/Linux gyda'r cmake arferol.

Y newyddion da yw y gellir adeiladu OpenCV fel llyfrgell sefydlog allan o'r bocs, sy'n ei gwneud hi'n haws cludo. Rydyn ni'n casglu llyfrgell gyda chyfluniad safonol ac yn gweld faint o le maen nhw'n ei gymryd. Cesglir pob modiwl mewn llyfrgell ar wahân.

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

Fel y gwelwch o'r llinell olaf, nid yw .bss a .data yn cymryd llawer o le, ond mae'r cod yn fwy na 70 MiB. Mae'n amlwg, os yw hyn wedi'i gysylltu'n statig â chymhwysiad penodol, bydd y cod yn dod yn llai.

Gadewch i ni geisio taflu cymaint o fodiwlau â phosibl fel bod enghraifft fach iawn yn cael ei rhoi at ei gilydd (a fydd, er enghraifft, yn allbynnu'r fersiwn OpenCV yn unig), felly rydyn ni'n edrych cmake .. -LA a diffodd yn yr opsiynau popeth sy'n troi i ffwrdd.

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

Ar y naill law, dim ond un modiwl o'r llyfrgell yw hwn, ar y llaw arall, mae hyn heb optimeiddio casglwr ar gyfer maint cod (-Os). ~ Mae 3 MiB o god yn dal yn gryn dipyn, ond mae eisoes yn rhoi gobaith am lwyddiant.

Rhedeg yn yr efelychydd

Mae'n llawer haws dadfygio ar yr efelychydd, felly yn gyntaf gwnewch yn siŵr bod y llyfrgell yn gweithio ar qemu. Fel platfform wedi'i efelychu, dewisais Integrator / CP, oherwydd yn gyntaf, mae hefyd yn ARM, ac yn ail, mae Embox yn cefnogi allbwn graffeg ar gyfer y platfform hwn.

Mae gan Embox fecanwaith ar gyfer adeiladu llyfrgelloedd allanol, gan ei ddefnyddio rydym yn ychwanegu OpenCV fel modiwl (gan basio'r un opsiynau ar gyfer yr adeilad "lleiaf" ar ffurf llyfrgelloedd statig), ar ôl hynny rwy'n ychwanegu cymhwysiad syml sy'n edrych fel hyn:

version.cpp:

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

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

    return 0;
}

Rydyn ni'n cydosod y system, yn ei rhedeg - rydyn ni'n cael yr allbwn disgwyliedig.

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 включены в сборку и т.п.>

Y cam nesaf yw rhedeg rhyw enghraifft, yn ddelfrydol un o'r rhai safonol a gynigir gan y datblygwyr eu hunain. ar eich gwefan. Rwy'n dewis canny synhwyrydd ffin.

Roedd yn rhaid ailysgrifennu'r enghraifft ychydig i arddangos y ddelwedd gyda'r canlyniad yn uniongyrchol yn y byffer ffrâm. Roedd yn rhaid i mi wneud hyn, oherwydd. swyddogaeth imshow() yn gallu tynnu delweddau trwy'r rhyngwynebau QT, GTK a Windows, na fydd, wrth gwrs, yn bendant yn y ffurfwedd ar gyfer STM32. Mewn gwirionedd, gellir rhedeg QT ar STM32F7Discovery hefyd, ond bydd hyn yn cael ei drafod mewn erthygl arall 🙂

Ar ôl eglurhad byr ym mha fformat mae canlyniad y synhwyrydd ymyl yn cael ei storio, rydyn ni'n cael delwedd.

OpenCV ar STM32F7-Darganfod

llun gwreiddiol

OpenCV ar STM32F7-Darganfod

Canlyniad

Yn rhedeg ar STM32F7Discovery

Ar 32F746GDISCOVERY mae yna nifer o adrannau cof caledwedd y gallwn eu defnyddio un ffordd neu'r llall

  1. 320KiB RAM
  2. Fflach 1MiB ar gyfer delwedd
  3. 8MiB SDRAM
  4. 16MiB QSPI NAND Fflach
  5. slot cerdyn microSD

Gellir defnyddio cerdyn SD i storio delweddau, ond yng nghyd-destun rhedeg enghraifft fach iawn, nid yw hyn yn ddefnyddiol iawn.
Mae gan yr arddangosfa gydraniad o 480 × 272, sy'n golygu y bydd y cof clustog ffrâm yn 522 beit ar ddyfnder o 240 did, h.y. mae hyn yn fwy na maint RAM, felly bydd y byffer ffrâm a'r domen (a fydd yn ofynnol, gan gynnwys ar gyfer OpenCV, i storio data ar gyfer delweddau a strwythurau ategol) wedi'u lleoli yn SDRAM, popeth arall (cof ar gyfer staciau ac anghenion system eraill ) yn mynd i RAM .

Os cymerwn y cyfluniad lleiaf ar gyfer STM32F7Discovery (taflu'r rhwydwaith cyfan, pob gorchymyn, gwneud pentyrrau mor fach â phosibl, ac ati) ac ychwanegu OpenCV gydag enghreifftiau yno, bydd y cof gofynnol fel a ganlyn:

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

I’r rhai nad ydynt yn gyfarwydd iawn â pha adrannau sy’n mynd i ble, egluraf: yn .text и .rodata cyfarwyddiadau a chysonion (yn fras, data darllen yn unig) yn gorwedd i mewn .data mae'r data yn gyfnewidiol, .bss mae yna newidynnau "niweidio", sydd, serch hynny, angen lle (bydd yr adran hon yn "mynd" i RAM).

Y newyddion da yw hynny .data/.bss dylai ffitio, ond gyda .text y drafferth yw nad oes ond 1MiB o gof i'r ddelwedd. Gellir ei daflu allan .text y llun o'r enghraifft a'i ddarllen, er enghraifft, o'r cerdyn SD i'r cof wrth gychwyn, ond mae fruits.png yn pwyso tua 330KiB, felly ni fydd hyn yn datrys y broblem: y rhan fwyaf .text yn cynnwys y cod OpenCV.

Ar y cyfan, dim ond un peth sydd ar ôl - llwytho rhan o'r cod ar fflach QSPI (mae ganddo ddull gweithredu arbennig ar gyfer mapio cof i fws y system, fel bod y prosesydd yn gallu cyrchu'r data hwn yn uniongyrchol). Yn yr achos hwn, mae problem yn codi: yn gyntaf, nid yw cof gyriant fflach QSPI ar gael yn syth ar ôl ailgychwyn y ddyfais (mae angen i chi gychwyn y modd mapio cof ar wahân), ac yn ail, ni allwch “fflachio” y cof hwn gyda cychwynnwr cyfarwydd.

O ganlyniad, penderfynwyd cysylltu'r holl god yn QSPI, a'i fflachio â llwythwr hunan-ysgrifenedig a fydd yn derbyn y deuaidd gofynnol trwy TFTP.

Canlyniad

Ymddangosodd y syniad i borthi'r llyfrgell hon i Embox tua blwyddyn yn ôl, ond dro ar ôl tro fe'i gohiriwyd am wahanol resymau. Un ohonynt yw cefnogaeth i libstdc ++ a'r llyfrgell dempledi safonol. Mae problem cefnogaeth C ++ yn Embox y tu hwnt i gwmpas yr erthygl hon, felly yma ni fyddaf ond yn dweud ein bod wedi llwyddo i gyflawni'r gefnogaeth hon yn y swm cywir i'r llyfrgell hon weithio 🙂

Yn y diwedd, goresgynnwyd y problemau hyn (o leiaf ddigon i'r enghraifft OpenCV weithio), a rhedodd yr enghraifft. Mae'n cymryd 40 eiliad hir i'r bwrdd chwilio am ffiniau gan ddefnyddio'r hidlydd Canny. Mae hyn, wrth gwrs, yn rhy hir (mae yna ystyriaethau ar sut i wneud y gorau o'r mater hwn, bydd yn bosibl ysgrifennu erthygl ar wahân am hyn rhag ofn y bydd llwyddiant).

OpenCV ar STM32F7-Darganfod

Fodd bynnag, y nod canolradd oedd creu prototeip a fydd yn dangos y posibilrwydd sylfaenol o redeg OpenCV ar STM32, yn y drefn honno, cyflawnwyd y nod hwn, hwre!

tl;dr: cyfarwyddiadau cam wrth gam

0: Lawrlwythwch ffynonellau Embox, fel hyn:

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

1: Gadewch i ni ddechrau trwy gydosod cychwynnydd a fydd yn "fflachio" gyriant fflach QSPI.

    make confload-arm/stm32f7cube

Nawr mae angen i chi ffurfweddu'r rhwydwaith, oherwydd. Byddwn yn uwchlwytho'r ddelwedd trwy TFTP. I osod y bwrdd a'r gwesteiwr cyfeiriadau IP, mae angen i chi olygu'r conf/rootfs/network.

Enghraifft ffurfweddu:

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 - cyfeiriad gwesteiwr lle bydd y ddelwedd yn cael ei llwytho, address - cyfeiriad y bwrdd.

Ar ôl hynny, rydyn ni'n casglu'r cychwynnydd:

    make

2: Llwythiad arferol y cychwynnwr (sori am y pun) ar y bwrdd - nid oes dim byd penodol yma, mae angen i chi ei wneud fel unrhyw gais arall am STM32F7Discovery. Os nad ydych chi'n gwybod sut i'w wneud, gallwch ddarllen amdano yma.
3: Llunio delwedd gyda chyfluniad ar gyfer OpenCV.

    make confload-platform/opencv/stm32f7discovery
    make

4: Detholiad o adrannau ELF i'w ysgrifennu i QSPI i 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

Mae sgript yn y cyfeiriadur conf sy'n gwneud hyn, felly gallwch chi ei redeg

    ./conf/qspi_objcopy.sh # Нужный бинарник -- build/base/bin/qspi.bin

5: Gan ddefnyddio tftp, lawrlwythwch qspi.bin.bin i yriant fflach QSPI. Ar y gwesteiwr, i wneud hyn, copïwch qspi.bin i ffolder gwraidd y gweinydd tftp (fel arfer / srv/tftp/ neu /var/lib/tftpboot/; mae pecynnau ar gyfer y gweinydd cyfatebol ar gael yn y dosbarthiadau mwyaf poblogaidd, a elwir fel arfer tftpd neu tftp-hpa, weithiau mae'n rhaid i chi wneud systemctl start tftpd.service i ddechrau).

    # вариант для tftpd
    sudo cp build/base/bin/qspi.bin /srv/tftp
    # вариант для tftp-hpa
    sudo cp build/base/bin/qspi.bin /var/lib/tftpboot

Ar Embox (h.y. yn y cychwynnydd), mae angen i chi weithredu'r gorchymyn canlynol (rydym yn cymryd bod gan y gweinydd y cyfeiriad 192.168.2.1):

    embox> qspi_loader qspi.bin 192.168.2.1

6: Gyda gorchymyn goto mae angen i chi "neidio" i gof QSPI. Bydd y lleoliad penodol yn amrywio yn dibynnu ar sut mae'r ddelwedd yn gysylltiedig, gallwch weld y cyfeiriad hwn gyda'r gorchymyn mem 0x90000000 (mae'r cyfeiriad cychwyn yn ffitio i mewn i ail air 32-bit y ddelwedd); bydd angen i chi hefyd fflagio'r pentwr -s, cyfeiriad y pentwr yw 0x90000000, er enghraifft:

    embox>mem 0x90000000
    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275
                      ↑           ↑
              это адрес    это  адрес 
                стэка        первой
                           инструкции

    embox>goto -i 0x9000c27f -s 0x20023200 # Флаг -i нужен чтобы запретить прерывания во время инициализации системы

    < Начиная отсюда будет вывод не загрузчика, а образа с OpenCV >

7: Lansio

    embox> edges 20

a mwynhewch y chwiliad ffin 40 eiliad 🙂

Os aiff rhywbeth o'i le - ysgrifennwch broblem i mewn ein cadwrfa, neu i'r rhestr bostio [e-bost wedi'i warchod], neu mewn sylw yma.

Ffynhonnell: hab.com

Ychwanegu sylw