Ман яке аз таҳиякунандагони системаи оператсионӣ ҳастам
Агар шумо чизе ба монанди "OpenCV дар board STM32" дар системаи ҷустуҷӯ нависед, шумо метавонед шумораи зиёди одамонеро пайдо кунед, ки ба истифодаи ин китобхона дар тахтаҳои STM32 ё дигар микроконтроллерҳо таваҷҷӯҳ доранд.
Якчанд видеоҳо мавҷуданд, ки аз рӯи ном, бояд чӣ заруриро нишон диҳанд, аммо одатан (дар ҳама видеоҳое, ки ман дидаам) дар тахтаи STM32 танҳо тасвир аз камера гирифта шуда буд ва натиҷа дар экран нишон дода мешавад, ва худи коркарди тасвир ё дар компютери муқаррарӣ ё дар тахтаҳои пурқувваттар анҷом дода мешуд (масалан, Raspberry Pi).
Чаро мушкил аст?
Маъруфияти дархостҳои ҷустуҷӯӣ бо он шарҳ дода мешавад, ки OpenCV маъмултарин китобхонаи биниши компютерӣ мебошад, ки ин маънои онро дорад, ки бештар таҳиягарон бо он шиносанд ва қобилияти иҷро кардани коди барои мизи корӣ дар микроконтроллер раванди таҳияро хеле осон мекунад. Аммо чаро то ҳол дорухатҳои маъмул барои ҳалли ин мушкилот вуҷуд надоранд?
Мушкилоти истифодаи OpenCV дар шаллҳои хурд бо ду хусусият алоқаманд аст:
- Агар шумо китобхонаро ҳатто бо маҷмӯи ҳадди ақали модулҳо тартиб диҳед, он танҳо ба хотираи флеши ҳамон STM32F7Discovery мувофиқат намекунад (ҳатто бе назардошти ОС) аз сабаби коди хеле калон (якчанд мегабайтҳои дастурҳо)
- Худи китобхона дар C++ навишта шудааст, ки маънои онро дорад
- Барои вақти мусбӣ дастгирӣ лозим аст (истисноҳо ва ғ.)
- Дастгирии кам барои LibC/Posix, ки одатан дар ОС барои системаҳои дарунсохт пайдо мешавад - ба шумо китобхонаи стандартии плюс ва китобхонаи қолаби стандартии STL (вектор ва ғайра) лозим аст.
Интиқол ба Embox
Чун маъмулӣ, пеш аз интиқол додани ҳама гуна барномаҳо ба системаи оператсионӣ, хуб аст, ки кӯшиш кунед, ки онро дар шакле, ки таҳиягарон пешбинӣ кардаанд, созед. Дар ҳолати мо, бо ин мушкилот вуҷуд надорад - рамзи сарчашмаро дар он пайдо кардан мумкин аст
Хабари хуш ин аст, ки 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 включены в сборку и т.п.>
Қадами навбатӣ иҷро кардани баъзе мисолҳо мебошад, беҳтараш яке аз намунаҳои стандартие, ки худи таҳиягарон пешниҳод мекунанд.
Барои намоиш додани тасвир бо натиҷа бевосита дар буфери чаҳорчӯба мисолро каме аз нав навиштан лозим буд. Ман бояд ин корро кунам, зеро. функсия imshow()
метавонад тавассути интерфейсҳои QT, GTK ва Windows тасвирҳоро кашад, ки албатта, дар конфигуратсияи STM32 нест. Дар асл, QT инчунин метавонад дар STM32F7Discovery кор кунад, аммо ин дар мақолаи дигар баррасӣ хоҳад шуд 🙂
Пас аз шарҳи кӯтоҳе, ки дар кадом формат натиҷаи детектори канор нигоҳ дошта мешавад, мо тасвир мегирем.
тасвири аслӣ
Дар натиҷа
Дар STM32F7Discovery кор мекунад
Дар 32F746GDISCOVERY якчанд қисмҳои хотираи сахтафзор мавҷуданд, ки мо метавонем бо ин ё он роҳ истифода барем.
- 320 КБ RAM
- 1МБ флеш барои тасвир
- SDRAM 8МБ
- 16MiB QSPI NAND Flash
- ковокии корти 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
тағйирёбандаҳои "nulled" вуҷуд доранд, ки бо вуҷуди ин, ба ҷои лозим аст (ин бахш ба RAM "меравад").
Хабари хуш ин аст .data
/.bss
бояд мувофиқ бошад, аммо бо .text
Мушкилот дар он аст, ки барои тасвир танҳо 1MiB хотира мавҷуд аст. партофтан мумкин аст .text
расмро аз мисол гиред ва онро, масалан, аз корти SD ба хотира ҳангоми оғозёбӣ хонед, аммо fruits.png тақрибан 330 киб вазн дорад, бинобар ин ин мушкилотро ҳал намекунад: аксари .text
аз рамзи OpenCV иборат аст.
Умуман, танҳо як чиз боқӣ мондааст - бор кардани як қисми код ба флеши QSPI (он дорои режими махсуси кор барои харитасозии хотира ба автобуси система мебошад, то протсессор мустақиман ба ин маълумот дастрасӣ пайдо кунад). Дар ин ҳолат, мушкилот ба миён меояд: якум, хотираи флеш-диски QSPI дарҳол пас аз бозоғозкунии дастгоҳ дастрас нест (шумо бояд режими харитаи хотираро алоҳида оғоз кунед) ва дуюм, шумо наметавонед ин хотираро бо "дурахш" кунед. боркунаки шинос.
Дар натиҷа, қарор дода шуд, ки ҳамаи рамзҳоро дар QSPI пайваст карда, онро бо боркунаки худнависӣ флешдор кунед, ки бинарии лозимиро тавассути TFTP қабул мекунад.
Дар натиҷа
Идеяи интиқоли ин китобхона ба Embox тақрибан як сол пеш пайдо шуда буд, аммо бо сабабҳои гуногун такрор ва такрор ба таъхир афтод. Яке аз онҳо дастгирии libstdc++ ва китобхонаи қолабҳои стандартӣ мебошад. Мушкилоти дастгирии C++ дар Embox аз доираи ин мақола берун аст, бинобар ин дар ин ҷо ман танҳо мегӯям, ки мо тавонистем ин дастгирӣро ба миқдори зарурӣ барои кор кардани ин китобхона ба даст орем 🙂
Дар ниҳоят, ин мушкилот бартараф карда шуданд (ҳадди аққал барои кор кардани мисоли OpenCV кофӣ аст) ва мисол иҷро шуд. Барои ҷустуҷӯи сарҳад бо истифода аз филтри Canny, 40 сонияи тӯлонӣ лозим аст. Ин, албатта, хеле тӯлонӣ аст (дар бораи чӣ гуна оптимизатсия кардани ин масъала мулоҳизаҳо мавҷуданд, дар сурати муваффақ шудан мумкин аст, ки дар ин бора мақолаи алоҳида нависед).
Аммо, ҳадафи мобайнӣ эҷоди як прототип буд, ки имкони бунёдии кор кардани 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: Иқтибос аз бахшҳои ELF бояд ба QSPI ба 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-битии тасвир мувофиқат мекунад); ба шумо инчунин лозим меояд, ки стекро қайд кунед -s
, суроғаи стек дар 0x90000000 аст, мисол:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
↑ ↑
это адрес это адрес
стэка первой
инструкции
embox>goto -i 0x9000c27f -s 0x20023200 # Флаг -i нужен чтобы запретить прерывания во время инициализации системы
< Начиная отсюда будет вывод не загрузчика, а образа с OpenCV >
7: Оғози
embox> edges 20
ва аз ҷустуҷӯи сарҳадии 40-сония лаззат баред 🙂
Агар чизе хато кунад - як масъала нависед
Манбаъ: will.com