STM32F7-Discovery پر OpenCV

STM32F7-Discovery پر OpenCV میں آپریٹنگ سسٹم کے ڈویلپرز میں سے ایک ہوں۔ ایمبوکس، اور اس مضمون میں میں اس بارے میں بات کروں گا کہ میں نے STM32746G بورڈ پر اوپن سی وی کو کیسے چلانے کا انتظام کیا۔

اگر آپ سرچ انجن میں "OpenCV on STM32 بورڈ" جیسی کوئی چیز ٹائپ کرتے ہیں، تو آپ کو بہت سے لوگ مل سکتے ہیں جو STM32 بورڈز یا دیگر مائیکرو کنٹرولرز پر اس لائبریری کو استعمال کرنے میں دلچسپی رکھتے ہیں۔
ایسی کئی ویڈیوز ہیں جن کے نام سے اندازہ لگاتے ہوئے یہ ظاہر کرنا چاہیے کہ کیا ضرورت ہے، لیکن عام طور پر (ان تمام ویڈیوز میں جو میں نے دیکھی ہیں) STM32 بورڈ پر، کیمرے سے صرف تصویر موصول ہوئی تھی اور نتیجہ اسکرین پر دکھایا گیا تھا، اور امیج پروسیسنگ بذات خود یا تو باقاعدہ کمپیوٹر پر، یا زیادہ طاقتور بورڈز (مثال کے طور پر، Raspberry Pi) پر کی گئی تھی۔

یہ مشکل کیوں ہے؟

تلاش کے سوالات کی مقبولیت کی وضاحت اس حقیقت سے ہوتی ہے کہ OpenCV کمپیوٹر وژن کی سب سے مشہور لائبریری ہے، جس کا مطلب ہے کہ زیادہ ڈویلپرز اس سے واقف ہیں، اور مائیکرو کنٹرولر پر ڈیسک ٹاپ کے لیے تیار کوڈ کو چلانے کی صلاحیت ترقی کے عمل کو بہت آسان بناتی ہے۔ لیکن اس مسئلے کو حل کرنے کے لئے ابھی تک کوئی مقبول تیار شدہ ترکیبیں کیوں نہیں ہیں؟

چھوٹی شالوں پر اوپن سی وی کے استعمال کا مسئلہ دو خصوصیات سے متعلق ہے:

  • اگر آپ ماڈیولز کے کم سے کم سیٹ کے ساتھ بھی لائبریری کو مرتب کرتے ہیں، تو یہ ایک بہت بڑے کوڈ (کئی میگا بائٹس کی ہدایات) کی وجہ سے اسی STM32F7Discovery (یہاں تک کہ OS کو مدنظر رکھے بغیر) کی فلیش میموری میں فٹ نہیں ہو گی۔
  • لائبریری خود C++ میں لکھی گئی ہے، جس کا مطلب ہے۔
    • مثبت رن ٹائم کے لیے سپورٹ کی ضرورت ہے (استثناء، وغیرہ)
    • LibC/Posix کے لیے بہت کم سپورٹ، جو عام طور پر ایمبیڈڈ سسٹمز کے لیے OS میں پایا جاتا ہے - آپ کو ایک معیاری پلس لائبریری اور ایک معیاری STL ٹیمپلیٹ لائبریری (ویکٹر، وغیرہ) کی ضرورت ہے۔

ایمباکس میں پورٹ کرنا

ہمیشہ کی طرح، کسی بھی پروگرام کو آپریٹنگ سسٹم میں پورٹ کرنے سے پہلے، اسے اس شکل میں بنانے کی کوشش کرنا ایک اچھا خیال ہے جس میں ڈویلپرز کا ارادہ تھا۔ ہمارے معاملے میں، اس کے ساتھ کوئی مسئلہ نہیں ہے - ماخذ کوڈ پر پایا جا سکتا ہے گیتھب، لائبریری GNU/Linux کے تحت معمول کے cmake کے ساتھ بنائی گئی ہے۔

اچھی خبر یہ ہے کہ اوپن سی وی کو باکس سے باہر ایک جامد لائبریری کے طور پر بنایا جا سکتا ہے، جو پورٹنگ کو آسان بناتا ہے۔ ہم ایک معیاری ترتیب کے ساتھ ایک لائبریری جمع کرتے ہیں اور دیکھتے ہیں کہ وہ کتنی جگہ لیتے ہیں۔ ہر ماڈیول کو ایک علیحدہ لائبریری میں جمع کیا جاتا ہے۔

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

ایک طرف، یہ لائبریری کا صرف ایک ماڈیول ہے، دوسری طرف، یہ کوڈ سائز کے لیے کمپائلر آپٹیمائزیشن کے بغیر ہے (-Os)۔ ~3 MiB کوڈ ابھی بھی کافی ہے، لیکن پہلے ہی کامیابی کی امید دیتا ہے۔

ایمولیٹر میں چلائیں۔

ایمولیٹر پر ڈیبگ کرنا بہت آسان ہے، اس لیے پہلے یہ یقینی بنائیں کہ لائبریری qemu پر کام کرتی ہے۔ ایک نقلی پلیٹ فارم کے طور پر، میں نے انٹیگریٹر/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 پر بھی چلایا جا سکتا ہے، لیکن اس پر کسی اور مضمون میں بحث کی جائے گی 🙂

ایک مختصر وضاحت کے بعد جس فارمیٹ میں ایج ڈیٹیکٹر کا نتیجہ محفوظ کیا جاتا ہے، ہمیں ایک تصویر ملتی ہے۔

STM32F7-Discovery پر OpenCV

اصل تصویر

STM32F7-Discovery پر OpenCV

نتیجہ

STM32F7Discovery پر چل رہا ہے۔

32F746GDISCOVERY پر ہارڈویئر میموری کے کئی حصے ہیں جنہیں ہم کسی نہ کسی طریقے سے استعمال کر سکتے ہیں۔

  1. 320KiB ریم
  2. تصویر کے لیے 1MiB فلیش
  3. 8MiB SDRAM
  4. 16MiB QSPI NAND فلیش
  5. مائیکرو ایس ڈی کارڈ سلاٹ

تصاویر کو ذخیرہ کرنے کے لیے ایک 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 وہاں "نیلڈ" متغیرات ہیں، جن کے باوجود، ایک جگہ کی ضرورت ہے (یہ سیکشن RAM میں "جائے گا")۔

اچھی خبر یہ ہے کہ .data/.bss فٹ ہونا چاہئے، لیکن ساتھ .text مصیبت یہ ہے کہ تصویر کے لیے صرف 1MiB میموری ہے۔ باہر پھینکا جا سکتا ہے۔ .text مثال سے تصویر لیں اور اسے پڑھیں، مثال کے طور پر، SD کارڈ سے سٹارٹ اپ میں میموری میں، لیکن fruits.png کا وزن تقریباً 330KiB ہے، اس لیے اس سے مسئلہ حل نہیں ہوگا: زیادہ تر .text OpenCV کوڈ پر مشتمل ہے۔

مجموعی طور پر، صرف ایک چیز باقی ہے - کوڈ کا ایک حصہ QSPI فلیش پر لوڈ کرنا (اس میں سسٹم بس میں میموری کو میپ کرنے کے لیے آپریشن کا ایک خاص طریقہ ہے، تاکہ پروسیسر اس ڈیٹا تک براہ راست رسائی حاصل کر سکے)۔ اس صورت میں، ایک مسئلہ پیدا ہوتا ہے: سب سے پہلے، QSPI فلیش ڈرائیو کی میموری ڈیوائس کے ریبوٹ ہونے کے فوراً بعد دستیاب نہیں ہوتی ہے (آپ کو میموری میپڈ موڈ کو الگ سے شروع کرنے کی ضرورت ہے)، اور دوسری بات، آپ اس میموری کو "فلیش" نہیں کر سکتے۔ ایک مانوس بوٹ لوڈر۔

نتیجے کے طور پر، QSPI میں تمام کوڈ کو لنک کرنے کا فیصلہ کیا گیا، اور اسے خود تحریر کردہ لوڈر کے ساتھ فلیش کریں جو TFTP کے ذریعے مطلوبہ بائنری حاصل کرے گا۔

نتیجہ

اس لائبریری کو ایمباکس میں پورٹ کرنے کا خیال تقریباً ایک سال قبل سامنے آیا، لیکن بار بار اسے مختلف وجوہات کی بنا پر ملتوی کر دیا گیا۔ ان میں سے ایک libstdc++ اور معیاری ٹیمپلیٹ لائبریری کے لیے سپورٹ ہے۔ Embox میں C++ سپورٹ کا مسئلہ اس مضمون کے دائرہ کار سے باہر ہے، اس لیے یہاں میں صرف اتنا کہوں گا کہ ہم اس لائبریری کے کام کرنے کے لیے صحیح مقدار میں اس سپورٹ کو حاصل کرنے میں کامیاب ہوئے 🙂

آخر میں، ان مسائل پر قابو پا لیا گیا (کم از کم OpenCV مثال کے کام کرنے کے لیے کافی ہے)، اور مثال چل گئی۔ کینی فلٹر کا استعمال کرتے ہوئے بورڈ کو حدود تلاش کرنے میں 40 طویل سیکنڈ لگتے ہیں۔ یہ، یقیناً، بہت طویل ہے (اس معاملے کو بہتر بنانے کے طریقے پر غور کیا جا رہا ہے، کامیابی کی صورت میں اس بارے میں ایک الگ مضمون لکھنا ممکن ہو گا)۔

STM32F7-Discovery پر OpenCV

تاہم، درمیانی مقصد ایک پروٹو ٹائپ بنانا تھا جو بالترتیب STM32 پر OpenCV چلانے کے بنیادی امکان کو ظاہر کرے گا، یہ مقصد حاصل ہو گیا، ہورے!

tl؛ dr: قدم بہ قدم ہدایات

0: ایمباکس کے ذرائع کو ڈاؤن لوڈ کریں، اس طرح:

    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 فلیش ڈرائیو پر qspi.bin.bin ڈاؤن لوڈ کریں۔ میزبان پر، ایسا کرنے کے لیے، 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 سیکنڈ کی بارڈر سرچ سے لطف اندوز ہوں 🙂

اگر کچھ غلط ہو جاتا ہے تو - اس میں ایک مسئلہ لکھیں۔ ہمارے ذخیرے، یا میلنگ لسٹ میں [ای میل محفوظ]، یا یہاں ایک تبصرہ میں۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں