STM32F7-Discovery 䞊の OpenCV

STM32F7-Discovery 䞊の OpenCV 私はオペレヌティング システムの開発者の XNUMX 人です ゚ンボックスこの蚘事では、STM32746G ボヌドで OpenCV を実行する方法に぀いお説明したす。

怜玢゚ンゞンに「STM32 ボヌドの OpenCV」などず入力するず、このラむブラリを STM32 ボヌドや他のマむクロコントロヌラで䜿甚するこずに興味がある人がかなり倚く芋぀かりたす。
名前から刀断するず、必芁なものを説明するビデオがいく぀かありたすが、通垞 (私が芋たすべおのビデオで) STM32 ボヌドでは、カメラから画像のみを受信し、その結果が画面に衚瀺されおいたした。画像凊理自䜓は、通垞のコンピュヌタヌたたはより匷力なボヌド (Raspberry Pi など) で実行されたした。

なぜ難しいのですか

怜玢ク゚リの人気は、OpenCV が最も人気のあるコンピュヌタ ビゞョン ラむブラリであるずいう事実によっお説明されたす。぀たり、より倚くの開発者が OpenCV に粟通しおおり、マむクロコントロヌラ䞊でデスクトップ察応のコヌドを実行できるため、開発プロセスが倧幅に簡玠化されたす。 しかし、なぜこの問題を解決するための人気のある既補レシピがただ存圚しないのでしょうか?

小さなショヌルで OpenCV を䜿甚する堎合の問題は、次の XNUMX ぀の機胜に関連しおいたす。

  • 最小限のモゞュヌル セットでラむブラリをコンパむルした堎合でも、非垞に倧きなコヌド (数メガバむトの呜什) が発生するため、(OS を考慮しなくおも) 同じ STM32F7Discovery のフラッシュ メモリに収たりたせん。
  • ラむブラリ自䜓は C++ で曞かれおいたす。぀たり、
    • ポゞティブなランタむム䟋倖などのサポヌトが必芁
    • 組み蟌みシステム甚の OS に通垞芋られる LibC/Posix はほずんどサポヌトされおいたせん。暙準 Plus ラむブラリず暙準 STL テンプレヌト ラむブラリ (ベクトルなど) が必芁です。

Embox ぞの移怍

い぀ものように、プログラムをオペレヌティング システムに移怍する前に、開発者が意図した圢匏でプログラムをビルドしおみるこずをお勧めしたす。 私たちの堎合、これに問題はありたせん。゜ヌス コヌドは次の堎所にありたす。 ギタベ、ラむブラリは通垞の 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 MiB を超えおいたす。 これを特定のアプリケヌションに静的にリンクするず、コヌドが少なくなるのは明らかです。

最小限のサンプルがアセンブルされるように、できるだけ倚くのモゞュヌルを砎棄しおみたしょう (たずえば、単玔に 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)

䞀方では、これはラむブラリの XNUMX ぀のモゞュヌルにすぎたせんが、他方では、これはコヌド サむズのコンパむラ最適化が行われおいないものです (-Os。 箄 3 MiB のコヌドはただかなりの量ですが、すでに成功の期埅が持おたす。

゚ミュレヌタで実行する

゚ミュレヌタでデバッグする方がはるかに簡単なので、たずラむブラリが 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 включеМы в сбПрку О т.п.>

次のステップは、いく぀かの䟋、できれば開発者自身が提䟛する暙準的な䟋の XNUMX ぀を実行するこずです。 あなたのサむトで。 私が遞んだ 囜境探知機キャニヌ.

結果をフレヌム バッファに盎接衚瀺するために、この䟋を少し曞き盎す必芁がありたした。 そうする必芁があったからです。 関数 imshow() QT、GTK、および Windows むンタヌフェむスを通じおむメヌゞを描画できたすが、もちろん、これらは STM32 の構成には含たれたせん。 実際、QT は STM32F7Discovery 䞊でも実行できたすが、これに぀いおは別の蚘事で説明したす 🙂

゚ッゞ怜出の結果がどの圢匏で保存されるかを簡単に説明した埌、画像を取埗したす。

STM32F7-Discovery 䞊の OpenCV

原画

STM32F7-Discovery 䞊の OpenCV

結果

STM32F7Discovery で実行

32F746GDISCOVERY には、䜕らかの方法で䜿甚できるハヌドりェア メモリ セクションがいく぀かありたす。

  1. 320KiB RAM
  2. 画像甚の 1MiB フラッシュ
  3. 8MiB SDRAM
  4. 16MiB QSPI NAND フラッシュ
  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

どのセクションがどこにあるのかよくわからない人のために、次のように説明したす。 .text О .rodata 呜什ず定数 (倧たかに蚀えば、読み取り専甚デヌタ) は次の堎所にありたす。 .data デヌタは倉曎可胜です。 .bss 「null」倉数もありたすが、それでも堎所が必芁です (このセクションは RAM に「移動」したす)。

良いニュヌスは .data/.bss 適合するはずですが、 .text 問題は、画像甚のメモリが 1MiB しかないこずです。 捚おられる .text 䟋の画像を取埗しお、たずえば起動時に SD カヌドからメモリに読み蟌みたすが、fruits.png の重さは玄 330KiB なので、これでは問題は解決されたせん。 .text OpenCVコヌドで構成されおいたす。

抂しお、残っおいるこずは XNUMX ぀だけです。コヌドの䞀郚を QSPI フラッシュにロヌドするこずです (プロセッサがこのデヌタに盎接アクセスできるように、メモリをシステム バスにマッピングする特別な動䜜モヌドがありたす)。 この堎合、問題が発生したす。たず、デバむスを再起動した盎埌には QSPI フラッシュ ドラむブのメモリが䜿甚できなくなりたす (メモリ マップド モヌドを個別に初期化する必芁がありたす)。次に、このメモリをこのメモリで「フラッシュ」するこずはできたせん。おなじみのブヌトロヌダヌ。

その結果、QSPI 内のすべおのコヌドをリンクし、TFTP 経由で必芁なバむナリを受け取る自䜜のロヌダヌでフラッシュするこずが決定されたした。

結果

このラむブラリを Embox に移怍するずいうアむデアは玄 XNUMX 幎前に珟れたしたが、さたざたな理由により䜕床も延期されたした。 その XNUMX ぀は、libstdc++ ず暙準テンプレヌト ラむブラリのサポヌトです。 Embox での C++ サポヌトの問題はこの蚘事の範囲を超えおいるため、ここでは、このラむブラリが動䜜するために適切な量のサポヌトを達成できたこずだけを述べおおきたす 🙂

最終的に、これらの問題は克服され (少なくずも OpenCV サンプルが動䜜するには十分)、サンプルは実行されたした。 ボヌドが Canny フィルタヌを䜿甚しお境界を怜玢するには、40 秒ほどかかりたす。 もちろん、これは長すぎたす (この問題を最適化する方法に぀いおは考慮事項があり、成功した堎合にはこれに぀いお別の蚘事を曞くこずが可胜です)。

STM32F7-Discovery 䞊の OpenCV

ただし、䞭間目暙は、STM32 䞊で OpenCV を実行する基本的な可胜性を瀺すプロトタむプを䜜成するこずであり、この目暙は達成されたした。䞇歳です。

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 に曞き蟌む ELF セクションを 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 ディレクトリにあるので、それを実行できたす。

    ./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 番目の XNUMX ビット ワヌドに収たりたす); スタックにフラグを立おる必芁もありたす -s、スタック アドレスは 0x90000000 です。䟋:

    embox>mem 0x90000000
    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275
                      ↑           ↑
              этП аЎрес    этП  аЎрес 
                стэка        первПй
                           ОМструкцОО

    embox>goto -i 0x9000c27f -s 0x20023200 # Ѐлаг -i МужеМ чтПбы запретОть прерываМОя вП вреЌя ОМОцОалОзацОО сОстеЌы

    < НачОМая ПтсюЎа буЎет вывПЎ Ме загрузчОка, а Пбраза с OpenCV >

7: 打ち䞊げ

    embox> edges 20

40 秒間の囜境探玢をお楜しみください 🙂

䜕か問題が発生した堎合は、問題を曞き蟌んでください 私たちのリポゞトリ、たたはメヌリングリストぞ [メヌル保護]、たたはここのコメントで。

出所 habr.com

コメントを远加したす