Men operatsion tizimni ishlab chiquvchilardan biriman
Agar siz qidiruv tizimiga βSTM32 doskasida OpenCVβ kabi biror narsani yozsangiz, STM32 platalarida yoki boshqa mikrokontrollerlarda ushbu kutubxonadan foydalanishga qiziqqan bir nechta odamni topishingiz mumkin.
Nomiga ko'ra, nima kerakligini ko'rsatishi kerak bo'lgan bir nechta videolar mavjud, lekin odatda (men ko'rgan barcha videolarda) STM32 platasida faqat kameradan tasvir olingan va natija ekranda ko'rsatilgan, va tasvirni qayta ishlashning o'zi oddiy kompyuterda yoki kuchliroq taxtalarda (masalan, Raspberry Pi) amalga oshirildi.
Nega qiyin?
Qidiruv so'rovlarining mashhurligi OpenCV kompyuterni ko'rishning eng mashhur kutubxonasi ekanligi bilan izohlanadi, ya'ni u bilan ko'proq ishlab chiquvchilar yaxshi tanish va mikrokontrollerda ish stoli uchun tayyor kodni ishga tushirish imkoniyati ishlab chiqish jarayonini sezilarli darajada osonlashtiradi. Lekin nima uchun bu muammoni hal qilish uchun hali ham mashhur tayyor retseptlar yo'q?
Kichkina ro'mollarda OpenCV dan foydalanish muammosi ikkita xususiyat bilan bog'liq:
- Agar siz kutubxonani minimal modullar to'plami bilan kompilyatsiya qilsangiz, u juda katta kod (bir necha megabayt ko'rsatmalar) tufayli bir xil STM32F7Discovery flesh-xotirasiga (hatto OTni hisobga olmagan holda) mos kelmaydi.
- Kutubxonaning o'zi C++ tilida yozilgan, ya'ni
- Ijobiy ish vaqti uchun yordam kerak (istisnolar va boshqalar).
- Odatda o'rnatilgan tizimlar uchun operatsion tizimda mavjud bo'lgan LibC/Posix uchun juda kam yordam - sizga standart plus kutubxonasi va standart STL shablon kutubxonasi (vektor va boshqalar) kerak.
Embox-ga ko'chirish
Odatdagidek, har qanday dasturni operatsion tizimga o'tkazishdan oldin, uni ishlab chiquvchilar mo'ljallangan shaklda yaratishga harakat qilish yaxshidir. Bizning holatda, bu bilan hech qanday muammo yo'q - manba kodini topish mumkin
Yaxshi xabar shundaki, OpenCV qutidan tashqarida statik kutubxona sifatida yaratilishi mumkin, bu esa portlashni osonlashtiradi. Biz standart konfiguratsiyaga ega kutubxonani yig'amiz va ular qancha joy egallashini ko'ramiz. Har bir modul alohida kutubxonada to'plangan.
> 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)
Oxirgi satrdan ko'rinib turibdiki, .bss va .data ko'p joy egallamaydi, lekin kod 70 MiB dan ortiq. Agar bu ma'lum bir dastur bilan statik ravishda bog'langan bo'lsa, kod kamroq bo'lishi aniq.
Minimal misol yig'ilishi uchun (masalan, OpenCV versiyasini chiqaradi) iloji boricha ko'proq modullarni tashlashga harakat qilaylik, shuning uchun biz ko'rib chiqamiz. cmake .. -LA
va variantlarda o'chadigan hamma narsani o'chirib qo'ying.
-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)
Bir tomondan, bu kutubxonaning faqat bitta moduli, boshqa tomondan, bu kod hajmi uchun kompilyatorni optimallashtirishsiz (-Os
). ~3 MiB kod hali ham juda ko'p, ammo muvaffaqiyatga umid qilmoqda.
Emulyatorda ishga tushiring
Emulyatorda disk raskadrovka qilish ancha oson, shuning uchun avval kutubxona qemu da ishlayotganiga ishonch hosil qiling. Emulyatsiya qilingan platforma sifatida men Integrator / CP ni tanladim, chunki birinchidan, bu ham ARM, ikkinchidan, Embox ushbu platforma uchun grafik chiqishni qo'llab-quvvatlaydi.
Embox-da tashqi kutubxonalarni yaratish mexanizmi mavjud, undan foydalanib, biz OpenCV-ni modul sifatida qo'shamiz (statik kutubxonalar ko'rinishidagi "minimal" qurish uchun bir xil variantlardan o'tib), shundan so'ng men shunday ko'rinadigan oddiy dasturni qo'shamiz:
version.cpp:
#include <stdio.h>
#include <opencv2/core/utility.hpp>
int main() {
printf("OpenCV: %s", cv::getBuildInformation().c_str());
return 0;
}
Biz tizimni yig'amiz, ishga tushiramiz - kutilgan natijani olamiz.
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 Π²ΠΊΠ»ΡΡΠ΅Π½Ρ Π² ΡΠ±ΠΎΡΠΊΡ ΠΈ Ρ.ΠΏ.>
Keyingi qadam, ba'zi bir misolni, yaxshisi ishlab chiquvchilarning o'zlari tomonidan taklif qilingan standartlardan birini ishga tushirishdir.
Natija bilan tasvirni to'g'ridan-to'g'ri ramka buferida ko'rsatish uchun misolni biroz qayta yozish kerak edi. Men buni qilishim kerak edi, chunki. funktsiyasi imshow()
QT, GTK va Windows interfeyslari orqali tasvirlarni chizishi mumkin, bu, albatta, STM32 konfiguratsiyasida bo'lmaydi. Aslida, QT STM32F7Discovery-da ham ishlashi mumkin, ammo bu boshqa maqolada muhokama qilinadi π
Chek detektorining natijasi qaysi formatda saqlanganligini qisqacha aniqlagandan so'ng, biz tasvirni olamiz.
original rasm
natija
STM32F7Discovery tizimida ishlaydi
32F746GDISCOVERY-da biz u yoki bu tarzda foydalanishimiz mumkin bo'lgan bir nechta apparat xotira bo'limlari mavjud.
- 320 Kb RAM
- Tasvir uchun 1MiB flesh
- 8MiB SDRAM
- 16MiB QSPI NAND Flash
- microSD karta uyasi
Tasvirlarni saqlash uchun SD-kartadan foydalanish mumkin, ammo minimal misolni ishga tushirish kontekstida bu juda foydali emas.
Displey 480 Γ 272 o'lchamga ega, ya'ni freymbufer xotirasi 522 bit chuqurlikda 240 32 bayt bo'ladi, ya'ni. bu RAM hajmidan kattaroqdir, shuning uchun ramka buferi va yig'ma (bu tasvirlar va yordamchi tuzilmalar uchun ma'lumotlarni saqlash uchun, shu jumladan OpenCV uchun kerak bo'ladi) SDRAMda joylashgan bo'ladi, qolgan hamma narsa (steklar va boshqa tizim ehtiyojlari uchun xotira) ) RAMga o'tadi.
Agar biz STM32F7Discovery uchun minimal konfiguratsiyani olsak (butun tarmoqni, barcha buyruqlarni chiqarib tashlash, steklarni iloji boricha kichikroq qilish va hokazo) va u erda misollar bilan OpenCV qo'shsak, kerakli xotira quyidagicha bo'ladi:
text data bss dec hex filename
2876890 459208 312736 3648834 37ad42 build/base/bin/embox
Qaysi bo'limlar qayerga borishini juda yaxshi bilmaganlar uchun men tushuntiraman: in .text
ΠΈ .rodata
ko'rsatmalar va konstantalar (taxminan aytganda, faqat o'qish uchun ma'lumotlar) yotadi .data
ma'lumotlar o'zgaruvchan, .bss
"nulled" o'zgaruvchilar mavjud, ular shunga qaramay, joy kerak (bu bo'lim RAMga "ketadi").
Yaxshi xabar shu .data
/.bss
mos kelishi kerak, lekin bilan .text
muammo shundaki, tasvir uchun faqat 1MiB xotira mavjud. Chiqib ketish mumkin .text
misoldagi rasmni o'qing va uni, masalan, ishga tushirish vaqtida SD-kartadan xotiraga o'qing, lekin fruits.png og'irligi taxminan 330KiB, shuning uchun bu muammoni hal qilmaydi: ko'pchilik .text
OpenCV kodidan iborat.
Umuman olganda, faqat bitta narsa qoldi - kodning bir qismini QSPI chirog'iga yuklash (u protsessor ushbu ma'lumotlarga to'g'ridan-to'g'ri kirishi uchun xotirani tizim avtobusiga joylashtirish uchun maxsus ish rejimiga ega). Bunday holda, muammo yuzaga keladi: birinchidan, QSPI flesh-diskining xotirasi qurilma qayta ishga tushirilgandan so'ng darhol mavjud bo'lmaydi (siz xotira xaritasi rejimini alohida ishga tushirishingiz kerak), ikkinchidan, siz ushbu xotirani "flesh" qila olmaysiz. tanish bootloader.
Natijada, QSPI-dagi barcha kodlarni bog'lash va uni TFTP orqali kerakli ikkilik faylni oladigan o'z-o'zidan yozilgan yuklagich bilan o'chirishga qaror qilindi.
natija
Ushbu kutubxonani Embox-ga ko'chirish g'oyasi taxminan bir yil oldin paydo bo'lgan, biroq u turli sabablarga ko'ra qayta-qayta qoldirilgan. Ulardan biri libstdc++ va standart shablon kutubxonasini qo'llab-quvvatlashdir. Embox-da C++-ni qo'llab-quvvatlash muammosi ushbu maqola doirasidan tashqarida, shuning uchun bu erda men shuni aytamanki, biz ushbu kutubxona ishlashi uchun kerakli miqdorda ushbu yordamga erisha oldik π
Oxir-oqibat, bu muammolar bartaraf etildi (hech bo'lmaganda OpenCV misoli ishlashi uchun etarli) va misol ishga tushirildi. Kengashga Canny filtri yordamida chegaralarni qidirish uchun 40 uzoq soniya kerak bo'ladi. Bu, albatta, juda uzoq (bu masalani optimallashtirish bo'yicha fikrlar mavjud, muvaffaqiyatga erishgan taqdirda bu haqda alohida maqola yozish mumkin bo'ladi).
Biroq, oraliq maqsad STM32-da OpenCV-ni ishga tushirishning fundamental imkoniyatlarini ko'rsatadigan prototipni yaratish edi, mos ravishda bu maqsadga erishildi, afsus!
tl; dr: bosqichma-bosqich ko'rsatmalar
0: Embox manbalarini quyidagi kabi yuklab oling:
git clone https://github.com/embox/embox && cd ./embox
1: QSPI flesh-diskini "chaqnadi" bo'lgan yuklash moslamasini yig'ishdan boshlaylik.
make confload-arm/stm32f7cube
Endi siz tarmoqni sozlashingiz kerak, chunki. Tasvirni TFTP orqali yuklaymiz. Kengash va xost IP manzillarini o'rnatish uchun siz conf/rootfs/tarmoqni tahrirlashingiz kerak.
Konfiguratsiyaga misol:
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
- rasm yuklanadigan xost manzili, address
- kengashning manzili.
Shundan so'ng biz yuklovchini yig'amiz:
make
2: Doskaga yuklash moslamasining odatiy yuklanishi (so'z uchun uzr) - bu erda aniq hech narsa yo'q, siz buni STM32F7Discovery uchun boshqa har qanday dastur kabi qilishingiz kerak. Agar buni qanday qilishni bilmasangiz, bu haqda o'qishingiz mumkin
3: OpenCV uchun konfiguratsiya bilan tasvirni kompilyatsiya qilish.
make confload-platform/opencv/stm32f7discovery
make
4: QSPI ga qspi.bin ga yoziladigan ELF bo'limlaridan ko'chirma
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 katalogida buni bajaradigan skript mavjud, shuning uchun uni ishga tushirishingiz mumkin
./conf/qspi_objcopy.sh # ΠΡΠΆΠ½ΡΠΉ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊ -- build/base/bin/qspi.bin
5: tftp-dan foydalanib, qspi.bin.bin faylini QSPI flesh-diskiga yuklab oling. Buni amalga oshirish uchun xostda qspi.bin faylini tftp serverining ildiz papkasiga nusxalash (odatda /srv/tftp/ yoki /var/lib/tftpboot/; mos server uchun paketlar odatda deb ataladigan eng mashhur tarqatishlarda mavjud. tftpd yoki tftp-hpa, ba'zan qilish kerak systemctl start tftpd.service
boshlamoq).
# Π²Π°ΡΠΈΠ°Π½Ρ Π΄Π»Ρ tftpd
sudo cp build/base/bin/qspi.bin /srv/tftp
# Π²Π°ΡΠΈΠ°Π½Ρ Π΄Π»Ρ tftp-hpa
sudo cp build/base/bin/qspi.bin /var/lib/tftpboot
Embox-da (ya'ni yuklash moslamasida) siz quyidagi buyruqni bajarishingiz kerak (biz serverda 192.168.2.1 manzili bor deb taxmin qilamiz):
embox> qspi_loader qspi.bin 192.168.2.1
6: Buyruq bilan goto
QSPI xotirasiga "sakrash" kerak. Muayyan joylashuv tasvirning qanday bog'langanligiga qarab o'zgaradi, siz ushbu manzilni buyruq bilan ko'rishingiz mumkin mem 0x90000000
(boshlang'ich manzil tasvirning ikkinchi 32 bitli so'ziga mos keladi); shuningdek, stekni belgilashingiz kerak bo'ladi -s
, stek manzili 0x90000000 da, masalan:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
β β
ΡΡΠΎ Π°Π΄ΡΠ΅Ρ ΡΡΠΎ Π°Π΄ΡΠ΅Ρ
ΡΡΡΠΊΠ° ΠΏΠ΅ΡΠ²ΠΎΠΉ
ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ
embox>goto -i 0x9000c27f -s 0x20023200 # Π€Π»Π°Π³ -i Π½ΡΠΆΠ΅Π½ ΡΡΠΎΠ±Ρ Π·Π°ΠΏΡΠ΅ΡΠΈΡΡ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠΈΡΡΠ΅ΠΌΡ
< ΠΠ°ΡΠΈΠ½Π°Ρ ΠΎΡΡΡΠ΄Π° Π±ΡΠ΄Π΅Ρ Π²ΡΠ²ΠΎΠ΄ Π½Π΅ Π·Π°Π³ΡΡΠ·ΡΠΈΠΊΠ°, Π° ΠΎΠ±ΡΠ°Π·Π° Ρ OpenCV >
7: ishga tushirish
embox> edges 20
va 40 soniyalik chegara qidiruvidan rohatlaning π
Agar biror narsa noto'g'ri bo'lsa - muammoni yozing
Manba: www.habr.com