እኔ ከኦፕሬቲንግ ሲስተም ገንቢዎች አንዱ ነኝ
እንደ “OpenCV on STM32 board” የመሰለ ነገር በፍለጋ ሞተር ውስጥ ከተተይቡ፣ ይህን ቤተ-መጽሐፍት ለመጠቀም ፍላጎት ያላቸውን ጥቂት ሰዎች በSTM32 ሰሌዳዎች ወይም ሌሎች ማይክሮ መቆጣጠሪያ ላይ ማግኘት ይችላሉ።
በስም በመመዘን አስፈላጊውን ነገር ማሳየት ያለባቸው ብዙ ቪዲዮዎች አሉ ነገር ግን አብዛኛውን ጊዜ (በያየኋቸው ሁሉም ቪዲዮዎች) በ STM32 ሰሌዳ ላይ ምስሉ ብቻ ከካሜራ የተገኘ ሲሆን ውጤቱም በስክሪኑ ላይ ታይቷል. እና የምስሉ ማቀናበሪያ እራሱ በመደበኛ ኮምፒዩተር ላይ ወይም ይበልጥ ኃይለኛ በሆኑ ሰሌዳዎች ላይ (ለምሳሌ Raspberry Pi) ተከናውኗል።
ለምን ይከብዳል?
የፍለጋ መጠይቆችን ተወዳጅነት የሚገለፀው OpenCV በጣም ታዋቂው የኮምፒዩተር እይታ ቤተ-መጽሐፍት ነው ፣ይህ ማለት ብዙ ገንቢዎች እሱን ያውቃሉ ማለት ነው ፣ እና ለዴስክቶፕ ዝግጁ የሆነ ኮድ በማይክሮ መቆጣጠሪያ ላይ የማስኬድ ችሎታ የእድገት ሂደቱን በእጅጉ ያቃልላል። ግን ይህንን ችግር ለመፍታት አሁንም ተወዳጅ የሆኑ ዝግጁ የሆኑ የምግብ አዘገጃጀት መመሪያዎች ለምን የሉም?
OpenCV በትናንሽ ሻውል ላይ የመጠቀም ችግር ከሁለት ባህሪያት ጋር የተያያዘ ነው።
- ቤተ መፃህፍቱን በትንሽ የሞጁሎች ስብስብ እንኳን ካጠናቀርክ፣ በቀላሉ ከተመሳሳይ STM32F7Discovery ፍላሽ ሜሞሪ ጋር አይገጥምም (ስርዓተ ክወናውን ከግምት ውስጥ ሳያስገባ እንኳን) በጣም ትልቅ በሆነ ኮድ (በርካታ ሜጋባይት መመሪያዎች)።
- ቤተ መፃህፍቱ ራሱ በC++ ተጽፏል፣ ይህ ማለት ነው።
- ለአዎንታዊ የሩጫ ጊዜ (ልዩነት፣ ወዘተ) ድጋፍ ይፈልጋሉ።
- ለ LibC/Posix ብዙ ጊዜ በስርዓተ ክወና ውስጥ ለሚገኘው ለሊብሲ/Posix ትንሽ ድጋፍ - መደበኛ እና መደበኛ የኤስቲኤል አብነት ቤተ-መጽሐፍት ያስፈልግዎታል (ቬክተር ፣ ወዘተ.)
ወደ ኢምቦክስ በማስተላለፍ ላይ
እንደተለመደው ማንኛውንም ፕሮግራሞችን ወደ ኦፕሬቲንግ ሲስተም ከማስተላለፍዎ በፊት ገንቢዎቹ ባሰቡበት ፎርም ለመስራት መሞከሩ ጥሩ ነው። በእኛ ሁኔታ, በዚህ ላይ ምንም ችግሮች የሉም - የምንጭ ኮድ በ ላይ ሊገኝ ይችላል
መልካም ዜናው 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 ሚቢ ኮድ አሁንም በጣም ብዙ ነው፣ ግን አስቀድሞ ለስኬት ተስፋ ይሰጣል።
በ emulator ውስጥ አሂድ
በ emulator ላይ ማረም በጣም ቀላል ነው፣ስለዚህ በመጀመሪያ ቤተ መፃህፍቱ በqemu ላይ መስራቱን ያረጋግጡ። እንደ የተመሰለ መድረክ ፣ Integrator / CP ን መርጫለሁ ፣ ምክንያቱም በመጀመሪያ ፣ እሱ ደግሞ ARM ነው ፣ እና ሁለተኛ ፣ 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 እና በዊንዶውስ በይነገጾች መሳል ይችላል ፣ እሱም በእርግጥ ፣ በእርግጠኝነት ለ STM32 ውቅር ውስጥ አይሆንም። በእውነቱ ፣ QT በ STM32F7Discovery ላይም ሊሠራ ይችላል ፣ ግን ይህ በሌላ ጽሑፍ ውስጥ ይብራራል 🙂
የጠርዝ ጠቋሚው ውጤት በየትኛው ቅርጸት እንደሚከማች አጭር ማብራሪያ ካገኘ በኋላ, ምስል እናገኛለን.
የመጀመሪያ ሥዕል
ውጤት
በSTM32F7Discovery ላይ በመስራት ላይ
በ32F746GDISCOVERY ላይ በአንድ ወይም በሌላ መንገድ ልንጠቀምባቸው የምንችላቸው በርካታ የሃርድዌር ሚሞሪ ክፍሎች አሉ።
- 320 ኪባ ራም
- 1ሚቢ ፍላሽ ለምስል
- 8ሚቢ SDRAM
- 16ሚቢ QSPI NAND ፍላሽ
- የማይክሮ ኤስዲ ካርድ ማስገቢያ
ኤስዲ ካርድ ምስሎችን ለማከማቸት ጥቅም ላይ ሊውል ይችላል, ነገር ግን አነስተኛውን ምሳሌ በማስኬድ አውድ ውስጥ, ይህ በጣም ጠቃሚ አይደለም.
ማሳያው የ 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
"የተሻሩ" ተለዋዋጮች አሉ, ሆኖም ግን, ቦታ ያስፈልጋቸዋል (ይህ ክፍል "ወደ RAM" ይሄዳል).
መልካም ዜናው ያ ነው .data
/.bss
ተስማሚ መሆን አለበት ፣ ግን ከ ጋር .text
ችግሩ ለምስሉ 1ሚቢ ማህደረ ትውስታ ብቻ መኖሩ ነው። ወደ ውጭ መጣል ይቻላል .text
ምስሉን ከምሳሌው ላይ አንብበው፣ ለምሳሌ ከኤስዲ ካርድ ወደ ማህደረ ትውስታ ሲነሳ፣ ፍሬው.png ግን 330 ኪ.ቢ ይመዝናል፣ ስለዚህ ይህ ችግሩን አይፈታውም: .text
የ OpenCV ኮድን ያካትታል.
በአጠቃላይ፣ የቀረው አንድ ነገር ብቻ ነው - የኮዱን የተወሰነ ክፍል በQSPI ፍላሽ ላይ መጫን (ማስታወሻውን ወደ ሲስተሙ አውቶቡስ ለማሰራት ልዩ የአሰራር ዘዴ አለው፣ ስለዚህም ፕሮሰሰሩ ይህንን ውሂብ በቀጥታ ማግኘት ይችላል)። በዚህ ሁኔታ አንድ ችግር ይፈጠራል-በመጀመሪያ የ QSPI ፍላሽ አንፃፊ ማህደረ ትውስታ መሳሪያው እንደገና ከተጀመረ በኋላ ወዲያውኑ አይገኝም (የማህደረ ትውስታ ካርታ ሁነታን ለየብቻ ማስጀመር ያስፈልግዎታል) እና በሁለተኛ ደረጃ ይህንን ማህደረ ትውስታ በ "ፍላሽ" ማድረግ አይችሉም. የታወቀ ቡት ጫኝ.
በውጤቱም, በ QSPI ውስጥ ያሉትን ሁሉንም ኮዶች ለማገናኘት ተወስኗል, እና በ TFTP በኩል የሚፈለገውን ሁለትዮሽ በሚቀበለው በራስ የተጻፈ ሎደር ያብሩት.
ውጤት
ይህንን ቤተ-መጽሐፍት ወደ ኢምቦክስ የማስገባት ሀሳብ ከአንድ አመት በፊት ታይቷል ነገር ግን በተደጋጋሚ በተለያዩ ምክንያቶች ለሌላ ጊዜ ተላልፏል። ከመካከላቸው አንዱ ለlibstdc++ እና መደበኛ አብነት ቤተ-መጽሐፍት ድጋፍ ነው። በኤምቦክስ ውስጥ ያለው የC++ ድጋፍ ችግር ከዚህ ጽሁፍ ወሰን በላይ ነው፣ስለዚህ እዚህ የምናገረው ለዚህ ቤተ-መጽሐፍት እንዲሰራ በትክክለኛው መጠን ይህንን ድጋፍ ማሳካት እንደቻልን ብቻ ነው 🙂
በመጨረሻ፣ እነዚህ ችግሮች ተሸንፈዋል (ቢያንስ የOpenCV ምሳሌ ለመስራት በቂ ነው) እና ምሳሌው ሮጠ። የ Canny ማጣሪያን በመጠቀም ቦርዱ ድንበሮችን ለመፈለግ 40 ረጅም ሰከንዶች ይወስዳል። ይህ በእርግጥ በጣም ረጅም ነው (ይህንን ጉዳይ እንዴት ማመቻቸት እንደሚቻል ላይ ግምት ውስጥ ይገባል, በተሳካ ሁኔታ ስለዚህ ጉዳይ የተለየ ጽሑፍ መጻፍ ይቻላል).
ሆኖም መካከለኛው ግብ በSTM32 ላይ OpenCVን የማስኬድ መሰረታዊ እድልን የሚያሳይ ፕሮቶታይፕ መፍጠር ነበር ፣ በቅደም ተከተል ፣ ይህ ግብ ተሳክቷል ፣ hooray!
tl;dr: ደረጃ በደረጃ መመሪያዎች
0፡ የEmbox ምንጮችን አውርድ፣ እንደዚህ፡
git clone https://github.com/embox/embox && cd ./embox
1፡ የQSPI ፍላሽ አንፃፊን “ፍላሽ” የሚያደርግ ቡት ጫኝ በመገጣጠም እንጀምር።
make confload-arm/stm32f7cube
አሁን አውታረ መረቡን ማዋቀር ያስፈልግዎታል, ምክንያቱም. ምስሉን በTFTP በኩል እንሰቅላለን። ሰሌዳውን ለማዘጋጀት እና የአይፒ አድራሻዎችን ለማስተናገድ 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: በቦርዱ ላይ የተለመደው የቡት ጫኚው መጫን (ይቅርታ ለ pun) - እዚህ ምንም የተለየ ነገር የለም, ለ 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
በኤምቦክስ (ማለትም በቡት ጫኚው ውስጥ) የሚከተለውን ትዕዛዝ መፈጸም ያስፈልግዎታል (አገልጋዩ 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 ሰከንድ የድንበር ፍለጋ 🙂 ይደሰቱ
የሆነ ችግር ከተፈጠረ - ችግርን ይጻፉ
ምንጭ: hab.com