OpenCV on STM32F7-Papanggihan

OpenCV on STM32F7-Papanggihan Abdi salah sahiji pamekar sistem operasi Embox, sarta dina artikel ieu kuring baris ngobrol ngeunaan kumaha kuring junun ngajalankeun OpenCV on dewan STM32746G.

Upami anjeun ngetik sapertos "OpenCV on STM32 board" kana mesin pencari, anjeun tiasa mendakan sababaraha jalma anu resep ngagunakeun perpustakaan ieu dina papan STM32 atanapi mikrokontroler anu sanés.
Aya sababaraha pidéo anu, ditilik ku nami, kedah nunjukkeun naon anu diperyogikeun, tapi biasana (dina sadaya pidéo anu kuring tingali) dina papan STM32, ngan ukur gambar anu ditampi tina kaméra sareng hasilna ditampilkeun dina layar. jeung ngolah gambar sorangan dipigawé boh dina komputer biasa, atawa dina papan leuwih kuat (Contona, buah prambus Pi).

Naha sesah?

Popularitas queries pilarian dijelaskeun ku kanyataan yén OpenCV nyaéta perpustakaan visi komputer pang populerna, nu hartina leuwih pamekar wawuh jeung eta, sarta kamampuhan pikeun ngajalankeun kode desktop-siap dina mikrokontroler greatly simplifies prosés ngembangkeun. Tapi naha aya kénéh euweuh populér resep siap-dijieun pikeun ngarengsekeun masalah ieu?

Masalah ngagunakeun OpenCV dina shawl leutik aya hubunganana sareng dua fitur:

  • Lamun compile perpustakaan sanajan kalawan set minimal tina modul, eta ngan saukur moal cocog kana mémori flash sarua STM32F7Discovery (malah tanpa nyokot kana akun OS) alatan kode anu kacida gedéna (sababaraha megabytes parentah).
  • Perpustakaan sorangan ditulis dina C ++, nu hartina
    • Peryogi dukungan pikeun waktos jalan anu positif (pangecualian, jsb.)
    • Saeutik dukungan pikeun LibC/Posix, anu biasana aya dina OS pikeun sistem anu dipasang - anjeun peryogi perpustakaan tambah standar sareng perpustakaan template STL standar (vektor, jsb.)

Porting ka Embox

Sakumaha biasa, sateuacan porting program naon waé kana sistem operasi, éta hadé pikeun nyobian ngawangun éta dina bentuk anu dituju ku pamekar. Dina kasus urang, teu aya masalah sareng ieu - kode sumber tiasa dipendakan dina github, perpustakaan diwangun dina GNU / Linux Ubuntu jeung cmake dawam.

Warta anu saé nyaéta OpenCV tiasa diwangun salaku perpustakaan statik tina kotak, anu ngagampangkeun porting. Urang ngumpulkeun perpustakaan kalawan config baku tur tingal sabaraha spasi maranéhna butuh nepi. Unggal modul dikumpulkeun dina perpustakaan misah.

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

Salaku bisa ningali tina garis panungtungan, .bss na .data teu butuh nepi teuing spasi, tapi kode nu leuwih ti 70 MiB. Ieu jelas yén lamun ieu statis numbu ka aplikasi husus, kode bakal jadi kirang.

Hayu urang cobian buang saloba modul anu mungkin supados conto minimal dirakit (anu, contona, ngan saukur bakal ngahasilkeun versi OpenCV), ku kituna urang tingali. cmake .. -LA sareng mareuman dina pilihan sadayana anu pareum.

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

Di hiji sisi, ieu ngan hiji modul perpustakaan, di sisi séjén, ieu tanpa optimasi compiler pikeun ukuran kode (-Os). ~3 kode MiB masih cukup loba, tapi geus méré harepan sukses.

Ngajalankeun dina émulator

Éta langkung gampang pikeun debug dina émulator, janten pastikeun yén perpustakaan dianggo dina qemu. Salaku platform emulated, kuring milih Integrator / CP, sabab firstly, eta oge ARM, jeung Bréh, Embox ngarojong kaluaran grafik pikeun platform ieu.

Embox gaduh mékanisme pikeun ngawangun perpustakaan éksternal, ngagunakeun éta kami nambihan OpenCV salaku modul (ngaliwatan sadaya pilihan anu sami pikeun ngawangun "minimal" dina bentuk perpustakaan statik), saatos éta kuring nambihan aplikasi saderhana sapertos kieu:

version.cpp:

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

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

    return 0;
}

Urang ngumpul sistem, ngajalankeun eta - urang meunang kaluaran ekspektasi.

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

Lengkah saterusna nyaéta ngajalankeun sababaraha conto, preferably salah sahiji standar ditawarkeun ku pamekar sorangan. dina situs anjeun. Abdi milih detektor wates canny.

Contona kudu rada ditulis ulang pikeun mintonkeun gambar jeung hasilna langsung dina pigura panyangga. Kuring kungsi ngalakukeun ieu, sabab. fungsi imshow() bisa ngagambar gambar ngaliwatan interfaces QT, GTK jeung Windows, nu, tangtosna, pasti moal di config pikeun STM32. Kanyataanna, QT ogé tiasa dijalankeun dina STM32F7Discovery, tapi ieu bakal dibahas dina tulisan anu sanés 🙂

Saatos klarifikasi pondok nu format disimpen hasil detektor ujung, urang meunang hiji gambar.

OpenCV on STM32F7-Papanggihan

gambar aslina

OpenCV on STM32F7-Papanggihan

hasil

Dijalankeun dina STM32F7Discovery

Dina 32F746GDISCOVERY aya sababaraha bagian mémori hardware anu urang tiasa nganggo hiji cara atanapi anu sanés.

  1. 320KiB RAM
  2. 1MiB flash pikeun gambar
  3. 8MiB SDRAM
  4. 16MiB QSPI NAND Flash
  5. slot kartu microSD

Hiji kartu SD bisa dipaké pikeun nyimpen gambar, tapi dina konteks ngajalankeun hiji conto minimal, ieu teu pisan mangpaat.
tampilan ngabogaan resolusi 480 × 272, nu hartina mémori framebuffer bakal 522 bait dina jero 240 bit, i.e. ieu leuwih ti ukuran RAM, jadi framebuffer jeung numpuk (anu bakal diperlukeun, kaasup pikeun OpenCV, pikeun nyimpen data pikeun gambar jeung struktur bantu) bakal lokasina di SDRAM, sagalana sejenna (memori pikeun tumpukan jeung kabutuhan sistem séjén). ) bakal balik ka RAM.

Lamun urang nyokot config minimum pikeun STM32F7Discovery (ngalungkeun kaluar sakabéh jaringan, sagala paréntah, nyieun tumpukan sakumaha leutik-gancang, jsb) jeung nambahkeun OpenCV kalawan conto aya, memori diperlukeun bakal kieu:

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

Pikeun maranéhanana anu teu pisan wawuh jeung nu bagian mana, Kuring bakal ngajelaskeun: di .text и .rodata parentah jeung konstanta (kasarna diomongkeun, data readonly) perenahna di .data datana bisa dirobah, .bss Aya variabel "nulled", nu, Tapi, perlu tempat (bagian ieu bakal "buka" ka RAM).

Warta alus éta .data/.bss kudu pas, tapi kalawan .text masalahna nyaeta ngan aya 1MiB memori pikeun gambar. Bisa dibuang .text gambar tina conto jeung maca eta, contona, tina kartu SD kana memori dina ngamimitian, tapi fruits.png weighs ngeunaan 330KiB, jadi ieu moal ngajawab masalah: paling .text diwangun ku kode OpenCV.

Sacara umum, ngan ukur aya hiji hal anu tinggaleun - ngamuat bagian kodeu kana lampu kilat QSPI (mibanda modeu operasi khusus pikeun mémori peta kana beus sistem, supados prosésor tiasa ngaksés data ieu langsung). Dina hal ieu, timbul masalah: kahiji, mémori QSPI flash drive teu sadia langsung saatos alat rebooted (anjeun kudu misah initialize mode memori-dipetakeun), sarta kadua, Anjeun teu bisa "flash" memori ieu kalawan. a bootloader akrab.

Hasilna, eta ieu mutuskeun pikeun numbu sakabeh kode dina QSPI, sarta flash eta kalawan loader timer ditulis anu bakal nampa binér diperlukeun via TFTP.

hasil

Gagasan pikeun port perpustakaan ieu ka Embox mucunghul ngeunaan sataun katukang, tapi leuwih sarta leuwih deui ditunda alatan sagala rupa alesan. Salah sahijina nyaéta dukungan pikeun libstdc ++ sareng perpustakaan template standar. Masalah pangrojong C ++ di Embox saluareun ruang lingkup artikel ieu, jadi di dieu kuring ngan bakal disebutkeun yen urang junun ngahontal rojongan ieu dina jumlah katuhu pikeun perpustakaan ieu jalan 🙂

Tungtungna, masalah ieu diatasi (sahenteuna cukup pikeun conto OpenCV tiasa dianggo), sareng conto éta jalan. Butuh 40 detik panjang pikeun dewan pikeun milarian wates nganggo saringan Canny. Ieu, tangtosna, panjang teuing (aya pertimbangan ngeunaan cara ngaoptimalkeun masalah ieu, bakal mungkin nulis artikel misah ngeunaan ieu bisi sukses).

OpenCV on STM32F7-Papanggihan

Nanging, tujuan panengah nyaéta nyiptakeun prototipe anu bakal nunjukkeun kamungkinan dasar pikeun ngajalankeun OpenCV dina STM32, masing-masing, tujuan ieu kahontal, hore!

tl;dr: step by step parentah

0: Unduh sumber Embox, sapertos kieu:

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

1: Hayu urang mimitian ku assembling bootloader nu bakal "flash" a QSPI flash drive.

    make confload-arm/stm32f7cube

Ayeuna anjeun kudu ngonpigurasikeun jaringan, sabab. Urang bakal unggah gambar via TFTP. Pikeun nyetel papan sareng alamat IP host, anjeun kedah ngédit conf/rootfs/network.

Conto konfigurasi:

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 - alamat host ti mana gambar bakal dimuat, address - alamat dewan.

Sanggeus éta, urang ngumpulkeun bootloader:

    make

2: The loading dawam tina bootloader (punten pikeun Pun) dina dewan - aya nanaon husus di dieu, anjeun kudu ngalakukeun hal eta kawas pikeun sagala aplikasi sejenna pikeun STM32F7Discovery. Upami anjeun henteu terang kumaha ngalakukeunana, anjeun tiasa maca ngeunaan éta di dieu.
3: Nyusun gambar sareng konfigurasi pikeun OpenCV.

    make confload-platform/opencv/stm32f7discovery
    make

4: Ékstrak tina bagian ELF pikeun ditulis ka QSPI ka 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

Aya skrip dina diréktori conf anu ngalakukeun ieu, ku kituna anjeun tiasa ngajalankeunana

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

5: Ngagunakeun tftp, ngundeur qspi.bin.bin ka QSPI flash drive. Dina host, pikeun ngalakukeun ieu, nyalin qspi.bin kana polder akar tina server tftp (biasana / srv / tftp / atanapi / var / lib / tftpboot /; bungkusan pikeun server anu cocog sayogi dina distribusi anu paling populér, biasana disebut. tftpd atanapi tftp-hpa, sakapeung anjeun kedah ngalakukeun systemctl start tftpd.service pikeun ngamimitian).

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

Dina Embox (nyaéta dina bootloader), anjeun kedah ngajalankeun paréntah di handap ieu (urang nganggap yén server ngagaduhan alamat 192.168.2.1):

    embox> qspi_loader qspi.bin 192.168.2.1

6: Kalayan paréntah goto anjeun kedah "luncat" kana mémori QSPI. Lokasi husus bakal rupa-rupa gumantung kana kumaha gambar numbu, anjeun tiasa ningali alamat ieu kalawan paréntah mem 0x90000000 (alamat mimiti pas kana kecap 32-bit kadua gambar); anjeun ogé bakal kedah bandéra tumpukan -s, alamat tumpukan aya dina 0x90000000, contona:

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

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

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

7: ngajalankeun

    embox> edges 20

sarta ngarasakeun pilarian wates 40 detik 🙂

Upami aya anu salah - tuliskeun masalah dina gudang urang, atawa ka milis [email dijaga], atanapi dina koméntar di dieu.

sumber: www.habr.com

Tambahkeun komentar