STM32F7-Discovery дээрх OpenCV

STM32F7-Discovery дээрх OpenCV Би үйлдлийн систем хөгжүүлэгчдийн нэг Embox, мөн энэ нийтлэлд би STM32746G самбар дээр OpenCV-г хэрхэн ажиллуулж чадсан тухай ярих болно.

Хэрэв та хайлтын системд "STM32 самбар дээрх OpenCV" гэх мэт зүйлийг бичвэл STM32 самбар эсвэл бусад микроконтроллерууд дээр энэ номын санг ашиглах сонирхолтой цөөнгүй хүмүүсийг олох боломжтой.
Нэрийг нь харахад юу хэрэгтэй байгааг харуулах хэд хэдэн видео байдаг, гэхдээ ихэвчлэн (миний үзсэн бүх видеон дээр) STM32 самбар дээр зөвхөн камераас зөвхөн дүрсийг хүлээн авч, үр дүн нь дэлгэц дээр гарч ирдэг. зураг боловсруулах нь өөрөө ердийн компьютер эсвэл илүү хүчирхэг самбар дээр (жишээлбэл, Raspberry Pi) хийгдсэн.

Яагаад хэцүү байдаг вэ?

Хайлтын асуулгууд түгээмэл болсон нь OpenCV нь хамгийн алдартай компьютерийн харааны номын сан бөгөөд энэ нь илүү олон хөгжүүлэгчид үүнийг мэддэг, микроконтроллер дээр ширээний кодыг ажиллуулах чадвар нь хөгжүүлэлтийн процессыг ихээхэн хялбаршуулдаг гэсэн үг юм. Гэхдээ яагаад энэ асуудлыг шийдэх алдартай бэлэн жор байдаггүй вэ?

Жижиг ороолт дээр OpenCV ашиглах асуудал нь хоёр онцлогтой холбоотой.

  • Хэрэв та номын санг хамгийн бага багц модультай ч гэсэн эмхэтгэсэн бол энэ нь маш том код (хэд хэдэн мегабайт заавар) тул ижил STM32F7Discovery-ийн флаш санах ойд (OS-ийг тооцохгүйгээр) багтахгүй болно.
  • Номын сан нь өөрөө C++ хэл дээр бичигдсэн байдаг нь
    • Эерэг ажиллах хугацаанд дэмжлэг хэрэгтэй (үл хамаарах зүйл гэх мэт)
    • LibC/Posix-ийн дэмжлэг бага байдаг бөгөөд энэ нь ихэвчлэн суулгагдсан системд зориулсан үйлдлийн системд байдаг - танд стандарт нэмэх номын сан, стандарт STL загварын номын сан (вектор гэх мэт) хэрэгтэй.

Embox руу шилжүүлж байна

Ердийнх шигээ аливаа программыг үйлдлийн системд шилжүүлэхээс өмнө түүнийг хөгжүүлэгчдийн хүссэн хэлбэрээр бүтээхийг оролдох нь зүйтэй. Манай тохиолдолд үүнтэй холбоотой ямар ч асуудал байхгүй - эх кодыг эндээс олж болно github, номын сан нь ердийн cmake-тэй GNU/Linux дор бүтээгдсэн.

Сайн мэдээ гэвэл OpenCV-ийг статик номын сан хэлбэрээр бүтээх боломжтой бөгөөд энэ нь зөөвөрлөхөд хялбар болгодог. Бид стандарт тохиргоотой номын сан цуглуулж, хэр их зай эзэлдэгийг хардаг. Модуль бүрийг тусдаа номын санд цуглуулдаг.

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

Сүүлийн мөрөөс харахад .bss болон .data нь тийм ч их зай эзэлдэггүй ч код нь 70 МБ-аас их байна. Хэрэв энэ нь тодорхой програмтай статик холбоотой байвал код багасах нь тодорхой байна.

Хамгийн бага жишээг цуглуулахын тулд аль болох олон модулиудыг хаяхыг хичээцгээе (жишээлбэл, энэ нь OpenCV хувилбарыг гаргах болно), тиймээс бид харцгаая. cmake .. -LA болон унтардаг бүх зүйлийг сонголтуудаас унтраа.

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

Нэг талаас, энэ нь номын сангийн зөвхөн нэг модуль, нөгөө талаас кодын хэмжээг хөрвүүлэгчийн оновчлолгүй (-Os). ~3 МБ код нь нэлээд их байгаа ч амжилтанд хүрэх найдварыг аль хэдийн өгсөн.

Эмулятор дээр ажиллуулна уу

Эмулятор дээр дибаг хийх нь илүү хялбар байдаг тул эхлээд номын сан qemu дээр ажиллаж байгаа эсэхийг шалгаарай. Дуурайсан платформын хувьд би Integrator / CP-ийг сонгосон, учир нь нэгдүгээрт, энэ нь бас ARM, хоёрдугаарт, Embox нь энэ платформд зориулсан график гаралтыг дэмждэг.

Embox нь гадаад номын санг бий болгох механизмтай бөгөөд үүнийг ашиглан бид OpenCV-ийг модуль болгон нэмдэг (статик номын сан хэлбэрээр "хамгийн бага" бүтээх бүх ижил сонголтуудыг дамжуулдаг), үүний дараа би иймэрхүү харагдах энгийн програмыг нэмж оруулав:

version.cpp:

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

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

    return 0;
}

Бид системийг угсарч, ажиллуулдаг - бид хүлээгдэж буй үр дүнг авдаг.

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

Дараагийн алхам бол хөгжүүлэгчид өөрсдөө санал болгодог стандарт жишээнүүдийн аль нэгийг ажиллуулах явдал юм. таны сайт дээр. би сонгосон хил илрүүлэгч canny.

Үр дүн бүхий зургийг шууд хүрээний буферт харуулахын тулд жишээг бага зэрэг дахин бичих шаардлагатай байв. Би үүнийг хийх ёстой байсан, учир нь. функц imshow() QT, GTK болон Windows интерфейсээр дамжуулан зураг зурах боломжтой бөгөөд энэ нь мэдээжийн хэрэг STM32-ийн тохиргоонд байхгүй болно. Үнэн хэрэгтээ QT-г STM32F7Discovery дээр ажиллуулж болно, гэхдээ энэ талаар өөр нийтлэлд хэлэлцэх болно 🙂

Ирмэг илрүүлэгчийн үр дүн ямар форматаар хадгалагдаж байгааг товч тодруулсны дараа бид зураг авах болно.

STM32F7-Discovery дээрх OpenCV

анхны зураг

STM32F7-Discovery дээрх OpenCV

үр дүн

STM32F7Discovery дээр ажиллаж байна

32F746GDISCOVERY дээр бид ямар нэгэн байдлаар ашиглаж болох хэд хэдэн техник хангамжийн санах ойн хэсгүүд байдаг.

  1. 320 киб RAM
  2. Зургийн хувьд 1МБ флаш
  3. 8МБ SDRAM
  4. 16MiB QSPI NAND Flash
  5. microSD картны үүр

SD картыг зураг хадгалахад ашиглаж болох боловч хамгийн бага жишээ ажиллуулахын тулд энэ нь тийм ч ашигтай биш юм.
Дэлгэц нь 480 × 272 нягтралтай бөгөөд энэ нь фреймбуфер санах ой нь 522 битийн гүнд 240 байт байх болно гэсэн үг юм. Энэ нь RAM-ийн хэмжээнээс их байгаа тул фреймбуфер ба овоо (энэ нь OpenCV-д, зураг болон туслах бүтцэд зориулсан өгөгдлийг хадгалахад шаардлагатай) SDRAM болон бусад бүх зүйл (стек болон бусад системийн хэрэгцээнд зориулсан санах ой)-д байрлах болно. ) RAM руу шилжих болно.

Хэрэв бид STM32F7Discovery-ийн хамгийн бага тохиргоог авч (бүхэл бүтэн сүлжээ, бүх командуудыг хаях, стекийг аль болох жижиг болгох гэх мэт) аваад жишээнүүдийн хамт OpenCV-г нэмбэл шаардлагатай санах ой дараах байдалтай байна.

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

Аль хэсгүүд хаашаа явж байгааг сайн мэдэхгүй хүмүүст би тайлбарлах болно: in .text и .rodata заавар болон тогтмол (ойролцоогоор, зөвхөн унших өгөгдөл) оршдог .data өгөгдөл өөрчлөгдөх боломжтой, .bss "Тэгсэн" хувьсагч байдаг бөгөөд тэдгээр нь хэдий ч газар хэрэгтэй (энэ хэсэг нь RAM руу "явах" болно).

Сайн мэдээ гэвэл тэр .data/.bss тохирох ёстой, гэхдээ хамт .text Асуудал нь зургийн хувьд ердөө 1МБ санах ой байгаа явдал юм. Шидэж болно .text жишээн дээрх зургийг аваад, жишээлбэл, эхлүүлэх үед SD картаас санах ой руу уншаарай, гэхдээ fruits.png нь ойролцоогоор 330KiB жинтэй тул энэ нь асуудлыг шийдэхгүй: ихэнх нь .text OpenCV кодоос бүрдэнэ.

Ерөнхийдөө ганц л зүйл үлдлээ - кодын нэг хэсгийг QSPI флэш дээр ачаалах (энэ нь санах ойг системийн автобусанд буулгах тусгай горимтой тул процессор энэ өгөгдөлд шууд хандах боломжтой). Энэ тохиолдолд асуудал гарч ирнэ: нэгдүгээрт, QSPI флаш дискний санах ойг төхөөрөмжийг дахин ачаалсны дараа шууд ашиглах боломжгүй (та санах ойн зураглалын горимыг тусад нь эхлүүлэх хэрэгтэй), хоёрдугаарт, та энэ санах ойг "анивчуулж" чадахгүй. танил ачаалагч.

Үүний үр дүнд QSPI дахь бүх кодыг холбож, TFTP-ээр дамжуулан шаардлагатай хоёртын файлыг хүлээн авах өөрөө бичсэн дуудагчаар анивчуулахаар шийдсэн.

үр дүн

Энэ номын санг Embox руу оруулах санаа жил орчмын өмнө гарч ирсэн ч янз бүрийн шалтгааны улмаас дахин дахин хойшилсон. Тэдний нэг нь libstdc++ болон стандарт загварын номын санд зориулсан дэмжлэг юм. Embox дахь C++-ийн дэмжлэгийн асуудал нь энэ нийтлэлийн хамрах хүрээнээс хэтэрсэн тул бид энэ номын сангийн ажиллахад шаардлагатай хэмжээгээр энэ дэмжлэгийг авч чадсан гэдгийг энд л хэлье 🙂

Эцэст нь эдгээр асуудлуудыг даван туулж (наад зах нь OpenCV жишээ ажиллахад хангалттай), жишээ нь ажиллав. Самбар Canny шүүлтүүр ашиглан хил хязгаарыг хайхад 40 урт секунд шаардлагатай. Энэ нь мэдээжийн хэрэг хэтэрхий урт байна (энэ асуудлыг хэрхэн оновчтой болгох талаар бодолтой байгаа бөгөөд амжилтанд хүрсэн тохиолдолд энэ талаар тусдаа нийтлэл бичих боломжтой болно).

STM32F7-Discovery дээрх OpenCV

Гэсэн хэдий ч завсрын зорилго нь OpenCV-ийг STM32 дээр ажиллуулах үндсэн боломжийг харуулах прототипийг бий болгох явдал байсан тул энэ зорилго биеллээ, өө!

tl; dr: алхам алхмаар зааварчилгаа

0: Embox эх сурвалжийг дараах байдлаар татаж авах:

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

1: QSPI флаш дискийг "анивчих" ачаалагчийг угсарч эхэлцгээе.

    make confload-arm/stm32f7cube

Одоо та сүлжээгээ тохируулах хэрэгтэй, учир нь. Бид зургийг TFTP-ээр дамжуулан байршуулах болно. Самбар болон хостын IP хаягийг тохируулахын тулд conf/rootfs/network-г засах хэрэгтэй.

Тохиргооны жишээ:

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 - зураг ачаалах хостын хаяг, address - удирдах зөвлөлийн хаяг.

Үүний дараа бид ачаалагчийг цуглуулдаг:

    make

2: Ачаалагчийн ердийн ачааллыг самбар дээр (хөгжсөнд уучлаарай) - энд тодорхой зүйл байхгүй, та STM32F7Discovery-ийн бусад програмын адил үүнийг хийх хэрэгтэй. Хэрэв та үүнийг яаж хийхээ мэдэхгүй байгаа бол энэ талаар уншиж болно энд.
3: OpenCV-д зориулсан тохиргоотой зураг эмхэтгэх.

    make confload-platform/opencv/stm32f7discovery
    make

4: QSPI руу qspi.bin руу бичих ELF хэсгүүдээс задлах

    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 санд үүнийг хийдэг скрипт байгаа тул та үүнийг ажиллуулж болно

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

5: Tftp ашиглан qspi.bin.bin файлыг QSPI флаш диск рүү татаж авна уу. Хост дээр үүнийг хийхийн тулд qspi.bin-ийг tftp серверийн үндсэн хавтас руу хуулна уу (ихэвчлэн /srv/tftp/ эсвэл /var/lib/tftpboot/; харгалзах серверийн багцууд нь ихэвчлэн гэж нэрлэгддэг түгээмэл тархацуудад байдаг. tftpd эсвэл tftp-hpa, заримдаа та хийх хэрэгтэй systemctl start tftpd.service эхлэх).

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

Embox дээр (жишээ нь ачаалагч дээр) та дараах тушаалыг гүйцэтгэх хэрэгтэй (бид сервер 192.168.2.1 хаягтай гэж үзэж байна):

    embox> qspi_loader qspi.bin 192.168.2.1

6: тушаалаар goto та QSPI санах ой руу "үсрэх" хэрэгтэй. Тодорхой байршил нь зураг хэрхэн холбогдсоноос хамаарч өөр өөр байх болно, та энэ хаягийг тушаалаар харж болно mem 0x90000000 (эхлэх хаяг нь зургийн хоёр дахь 32 бит үгэнд багтах болно); та мөн стекийг дарцаглах хэрэгтэй болно -s, стек хаяг нь 0x90000000, жишээ нь:

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

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

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

7: эхлүүлэх

    embox> edges 20

мөн 40 секундын хилийн хайлтыг сайхан өнгөрүүлээрэй 🙂

Хэрэв ямар нэг зүйл буруу болбол - хэсэгт асуудал бичнэ үү манай агуулах, эсвэл шуудангийн жагсаалт руу оруулна уу [имэйлээр хамгаалагдсан], эсвэл энд сэтгэгдэл дээр бичнэ үү.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх