گنوم، چندسال اخیر رو در حال بهبود تجربه کاربریش روی دستگاههایی مثل گوشیهای همراه و همچنین تبلتهاست. در کل، داره برای یک انقلاب در صفحات لمسی آماده میشه. حالا، یک رابط کاربری جالب به اسم Phosh (مخففی برای Phone Shell) ارائه کرده که روی دبیان (بله، حتی دسکتاپ!) قابل نصب و اجراست.
نماگرفت زیر، نماگرفتی از صفحه قفل این رابط کاربریه:
و خب همونطوری که میبینید، کار تمیز و نسبتا زیباییه. حالا سوال اینه چطور نصبش کنیم؟ در ادامه مطلب مفصلا توضیح میدم 🙂
نصب قدم به قدم Phosh روی دبیان
گام اول: نصب دبیان
توجه داشته باشید که دبیان مد نظر من اینجا، دبیانیه که شما روی پردازندههای x86 نصب میکنید. اگر قراره این دبیان روی رزبری پای باشه، یا سیستم شخصی شما صفحه لمسی داره، میتونید این قسمت رو نادیده بگیرید. اما من نصب رو روی یک ماشین مجازی با کمک Virtual Box انجام دادم. آموزش نصب دبیان، در اینترنت زیاد پیدا میشه؛ فلذا اینجا حرفی از آموزش نصب به میان نمیارم. فقط حواستون باشه نسخه Net Install دبیان رو دانلود و نصب کنید که چیز اضافهای نداشته باشیم. برای دانلود دبیان هم میتونید به وبسایت دبیان مراجعه کنید و آخرین ISO مورد نظر رو بگیرید.
گام دوم: قبل از نصب Phosh چه کنیم؟
خب اولین کاری که قبل از نصب Phosh کنید اینه که با خودتون یک فنجان قهوه یا نوشیدنی خنک داشته باشید چون پروسه نصب ممکنه شما رو خسته و تشنه کنه. بعد از اون، بد نیست که سیستم رو بروزرسانی کنید. بعد از بروزرسانی سیستمعامل، نوبتی هم باشه نوبت اینه که مستقیم بریم سر نصب Phosh. اینجا هم جا داره نکته مهم رو متذکر بشم که من phosh رو از مخازن نصب میکنم تا صرفا کنجکاوی رفع شده باشه وگرنه روش درستتر نصب phosh نصب از کد منبعه (حداقل اگر روی سیستم x86 و به قصد توسعه نصب میکنید).
گام سوم: نصب و راهاندازی Phosh
خب برای نصب کافیه که دستورات زیر رو اجرا کنیم:
sudo apt install phosh-core
و اگر میخواهید Phosh شما مناسب تبلت باشه:
sudo apt install phosh-tablet
و اگر میخواهید نسخه کامل Phosh رو نصب کنید، کافیه که دستور رو به این شکل تغییر بدید:
sudo apt install phosh-full
و بعد از نصب حدود یک گیگابایت بستههای نرمافزاری، کل میزکار گنوم مخصوص صفحات لمسی یا همون Phosh برای شما نصب خواهد شد. پس از نصب، کافیه که اول سرویسش رو فعال و سپس راهاندازی کنیم:
سپس، صفحه قفل (که بالاتر عکسش رو قرار دادم) و بعد از اون، صفحه ورود رمز به شما نمایش داده میشه.
پس از ورود رمز، وارد صفحه منوی اصلی میشیم که از اونجا میتونیم به نرمافزارها و ابزارهای نصب شده روی سیستم دسترسی داشته باشیم:
خب، حالا با خیال راحت میتونیم از Phosh استفاده کنیم و لذت ببریم 😁
نکات مهم
از اونجایی که Phosh نرمافزار نوپا و نسبتا جدیدیه، لازمه چند نکته مهم رو در موردش متذکر بشم:
نسخه خاصی ازش در مخازن دبیان پایدار موجوده که خب برای یک تست دم دستی و ویرچوالباکسی، بهترین گزینه بود (حداقل برای من) و خب قاعدتا روی مخازن تستینگ و ناپایدار هم قرارش دادند. موقع نصب، مراقب باشید تا به ضررتون نشه 😁 ترجیحا نصب رو روی یک ماشین مجازی انجام بدید.
این میزکار خاص، برای صفحات لمسی خیلی بهینه شده و استفاده ازش با ماوس و کیبرد تا حد زیادی سخته. اگر صفحه لمسی دارید که میتونید به سیستمتون وصلش کنید، احتمالا تجربه کاربری بهتری داشته باشید.
بعضی نرمافزارها اندازهشون برای من مشکل داشت (که احتمالا برمیگرده به ویرچوال باکس). اگر در جای دیگری امتحان بشه شاید اندازه صفحه و برنامهها، مناسب باشه.
کدوم توزیعها از Phosh پشتیبانی میکنند؟
این هم سوال مهمیه، تا جایی که دیدم PostmarketOS (که برمبنای آلپاین ساخته شده) و همچنین Mobian (که برپایه دبیانه) از این میزکار (یا بهتر بگم پوسته) پشتیبانی میکنند. در مورد سایر توزیعها/سیستمعاملهایی که ممکنه گنوم رو اجرا کنند، ایدهای ندارم.
جمعبندی
این بلاگ اصلا قرار نبود نوشته شه، ولی امروز از سر خستگی (دقیقا خستگی 😂) جستجو کردم ببینم Phosh چطور میتونه روی دبیان دسکتاپ نصب بشه. امتحانش کردم و به نظرم پروژه تمیز، باحال و آیندهداری اومد. حالا هم تستش کردم و هم یک سری ایده اومد به ذهنم. در آینده، احتمالا بیشتر با Phosh کار کنم و در موردش بنویسم. در آخر هم بابت وقتی که صرف کردید و این مطلب رو خوندید، ازتون تشکر میکنم.
حدود بهمن یا اسفند سال ۱۳۹۹ بود که من، یک عدد رزبری پای ۴ مدل B (لینک) خریداری کردم که باهاش یه سری ایده رو عملی کنم. از وقتی که این دستگاه رو خریدم، مدت زیادی تقریبا گذشته اما خب چند هفته اخیر، شدیدا با این دستگاه در حال کشتی گرفتن و تست ایدههای مختلف هستم. یکی از ایدههای من پروژهای بود که تا حد زیادی به هوش مصنوعی (و بخصوص tensorflow) نیازمند بود. مشکلی که داشتم این بود که در خود مخازن PyPi ای که روی رزبری پای در دسترسه، هیچ ساخت درستی از tensorflow وجود نداره.
اما خب، نمیشه در دنیای تِک ناامید شد؛ به همین خاطر دنبال راهکار و راه حلی گشتم که بتونم تنسرفلو رو روی رزبری پای داشته باشم. یکم سختتر از حالت عادی (که استفاده از pip بود) شد اما ارزشش رو داشت. چون تونستم بدون مشکل مدلی که مدنظر داشتم رو لود و استفاده کنم. همچنین لازمه ذکر کنم که در این مطلب قراره یاد بگیریم چطور خود تنسرفلو رو نصب کنیم و به TFLite کاری نداریم.
رزبری پای چیه؟
رزبری پای (Raspberry Pi) یک کامپیوتر تکبرد (SBC یا Single Board Computet) محسوب میشه که توسط یک بنیاد غیرانتفاعی به همین اسم در بریتانیا طراحی شده (البته تولیدش مثل عمده محصولات دیگر، در کشور چین انجام میشه). این بردها معمولا یک پردازنده ARM دارند و میشه روی اونها سیستمعامل نصب کرد. خیلیهاشون هم ورودی/خروجی عاممنظوره (General Purpose Input/Output) یا همون GPIO دارند که میتونن رابطی بین این کامپیوتر و قطعات الکترونیکی دیگر باشند.
این کامپیوترهای کوچک – که در ابعاد یک کارت اعتباری ساخته شدند – اسباببازی خوبی برای برنامهنویسان و مهندسین کامپیوتر به شمار میان. بسیاری از متخصصین و علاقمندان از رزبری پای استفاده میکنن تا ایدهها و پروژههاشون رو پیادهسازی کنن. البته لازم به ذکره که خیلیها هم حتی محصولاتشون رو برپایه رزبریپای توسعه دادند (پس اگر دوست داشتید یکی تهیه کنید و باهاش بازی کنید، درنگ نکنید 😁)
تنسرفلو چیه؟
از اونجایی که این مطلب، در مورد نصب Tensorflow روی رزبری پای بود، لازمه که کمی هم در مورد تنسرفلو توضیح داده بشه. تنسرفلو یک کتابخونه نرمافزاری آزاد و متنبازه که توسط تیم Google Brain توسعه داده میشه. این کتابخونه، به ما اجازه میده که پروژهها و پروسههای یادگیری ماشین، هوش مصنوعی، یادگیری عمیق، استنباط آماری و … تا توسعه شبکههای عصبی مصنوعی رو انجام بدیم. به خاطر پشتیبانی گوگل از این کتابخونه، به یکی از محبوبترین و پراستفادهترین کتابخونههای هوش مصنوعی تبدیل شده (مثلا در پروژه خودران، من از این کتابخونه استفاده کرده بودم).
اما یک مشکل بزرگی با نصب تنسرفلو روی رزبری پای مواجه هستیم. مشکل اینجاست که وقتی دستور روتین pip برای نصب تنسرفلو رو بزنیم، اتفاق خیلی خاصی رخ نمیده، جز این که یک ارور مبنی بر پیدا نشدن این کتابخونه در مخازن PyPi متعلق به پلتفرم ما نشون داده میشه. پس باید چی کار کنیم؟ خب در ادامه قراره که همین داستان رو بررسی کنیم و به نتیجه درستی برسیم.
نصب Tensorflow روی Raspberry Pi
قبل از هرچیزی باید بگم که من این پروسه رو روی Raspberry Pi 4 Model B (با رم ۲ گیگابایت) و سیستم عامل Raspberry Pi OS نسخه Bullseye (بله درست حدس زدید، سیستمعامل رزبری پای دبیانه 😁 و صدالبته که میتونید توزیعهای دیگری هم روش نصب کنید) و ویرایش ۶۴ بیتی طی کردم. بسته به مدل رزبری شما و سیستمعاملتون، این پروسه میتونه متفاوت باشه.
نصب نرمافزارهای پایه
ما برای این که بتونیم تنسرفلو رو نصب کنیم، نیاز به نصب تعداد زیادی نرمافزار روی خود سیستمعامل داریم. به نظر بهتره که ابتدا، لیست بستههای مخازن رو بروزرسانی کنیم:
sudo apt update
و صدالبته بهتره که خود سیستمعامل هم بروزرسانیهای آخرش رو دریافت و نصب کنه:
sudo apt full-upgrade
پس از این که این مراحل انجام شد، تعداد زیادی نرمافزار رو به این شکل نصب میکنیم:
عمده این نرمافزارها رو بر اساس پیامهای خطایی که دریافت میکردم پیدا کردم، چرا که وقتی شما روی سیستم دسکتاپ یا لپتاپ خودتون تنسرفلو نصب میکنید، بسیاری از اینها (متناسب با معماری پردازنده) پیشتر نصب شدند اما سیستمعاملهایی که روی رزبری نصب میکنیم چنین حالتی ندارند. بهرحال، همه نرمافزارهای پایهای که نیازه از مخزن دبیان نصب بشه، در این دستور موجوده (طبیعتا اگر نیاز به بسته دیگری باشه بعدا این مطلب ویرایش میشه)
نصب و بروزرسانی بسته های پایتونی
خب ما تعدادی پیشنیاز پایتونی هم داریم (که اینها رو اکثرا حتی در وبسایت تنسرفلو هم میشه پیدا کرد) که با دستورات زیر نصبشون میکنیم:
توجه کنید که اگر این دستور کار نکرد هم جای نگرانی نیست، میتونید این لینک رو باز کنید و فایل رو خودتون دانلود کنید.
سپس کافیه که با اجرای این دستور:
pip3 install <TENSORFLOW WHL FILE>.whl
نصب رو انجام بدید.
ضمنا، از اونجایی که ممکنه بعدتر نسخهها تغییر کنن، بهتره که این صفحه رو هم هر چند وقت یه بار چک کنید تا اگر نیاز بود نسخه تنسرفلو رو تغییر بدید، فایل مربوطه رو دانلود کنید.
جمعبندی
مدتهای زیادی میشه که دوست دارم در مورد پروژههایی که در حوزه «اینترنت چیزها» یا همون IoT انجام میدم هم بنویسم. اما متاسفانه پروژههای سختافزاری، وقت زیادی از آدم میگیرن و وقتی وقت آزاد زیادی نداشته باشید، معمولا به پروژههای سختافزاریتون هم آنچنان نمیتونید رسیدگی کنید. به همین خاطر مدتی میشه که در تلاشم تا پروژههای شخصی و صدالبته کاریم در حوزه بینایی ماشین رو با IoT ترکیب کنم و به این شکل این حوزه رو هم وارد کارهای روتین و اصلیم کنم که وقت هم همیشه براشون باشه 😁
تست چند پروژه بینایی ماشین روی Raspberry Pi شروعی برای این دوران از زندگی منه. راستی، اگر دوست دارید نقشه راه بینایی ماشین رو داشته باشید میتونید بیایید اینجا، اگر دنبال ایده برای پروژهها هستید هم اینجا رو بخونید. حتی میتونید به ما در جامعه بینایی ماشین هم ملحق بشید و اشتراک تجربه و دانش کنید.
در دنیای امروز، یکی از بحثهای مهم برای هر استارتاپ و سازمانی، اینه که چطور و با چه ابزاری، محصول خودشون رو بسازند. این موضوع میتونه از لحظه تصمیمگیری برای راهاندازی استارتاپ در ذهن بنیانگذاران باشه، حین پیادهسازی محصول کمینه ارزشمند (MVP) ذهنشون رو بیشتر درگیر کنه و حتی پس از ارائه محصول نهایی هم همیشه فکر بازسازی و بازنویسی محصول یکی از مشغلههای ذهنیشون باقی بمونه. چند وقت اخیر، یکی از فازهایی که میان خیلی از برنامهنویسان – بخصوص نسل جدید و تازهنفس برنامهنویس – رایج شده، استفاده از گولنگ در ساخت MVP و … است.
در این پست، قصد من اینه که توضیح بدم چرا گولنگ انتخاب مناسبی نیست و چرا بهتره که در یک سازمان کوچک، سمتش نریم و از ابزارهای دمدستیتری مثل پایتون یا PHP استفاده کنیم. ضمنا اینجا یک سلب ادعا بکنم که «دمستی» به معنای «بد» بودن اون ابزار نیست و اتفاقا در این متن بخصوص، یک مزیت برای اون ابزار ایجاد کرده.
چطور برای پروژه خود یک زبان یا فرمورک مناسب انتخاب کنیم؟
مطلب اصلی، در واقع اینجا شروع میشه. در این قسمت یک سری ویژگی رو کنار هم میچینیم و گولنگ رو در کنار ابزارهای قدیمیتر مثل PHP یا پایتون قرار میدیم که ببینیم کدوم یکی برنده از میدان بیرون میاد و اگر قراره که یک استارتاپ راه بندازیم، محصولمون رو با کدوم یکی از این ابزارها بنویسیم. توجه هم داشته باشید که این بخش متاثر از نظرات شخصی من هم هست و طبیعتا ازتون میخوام که در نقدهایی که به این مطلب وارد میکنید، این مورد هم در نظر بگیرید.
جمعیت توسعهدهندگان
مهمترین فاکتور در انتخاب زبان و فرمورک برنامهنویسی، دقیقا جمعیت توسعهدهندگان اونه. میپرسید چرا؟ چون اگر امروز خودتون کد رو بزنید، طبیعتا وقتی بیشتر با جنبه بیزنسی کارتون مواجه شید، وقت کمتری برای کد زدن خواهید داشت و نیازمند بزرگتر کردن تیم توسعه استارتاپتون هستید. پس از این جهت نیاز دارید که این مورد رو حتما در نظر بگیرید. دقت کنید که Go از سال ۲۰۰۹ عرضه عمومی شده و چندین ساله که داره بعنوان یک ابزار توسعه وب دیده میشه (که تعداد این سالها به انگشتای دست هم نمیرسه).
حالا از طرف دیگر، شما نگاه کنید که چقدر میتونید لاراولکار پیدا کنید؟ افرادی که لاراول یا جنگو (یا حتی روبی آن ریلز!!!) کار میکنند تعدادشون به شدت بیشتر از کسانیه که با Go کار میکنند. نتیجه منطقی اینه که سمت ابزاری برید که بزرگ کردن تیم توسعهش براتون کمهزینه باشه.
تعداد کتابخانهها و ابزارهای توسعه
مورد مهمی که باید بهش توجه کنید، اینه که زبان مورد استفادهتون چقدر ابزار داره؟ چندتا ORM استخواندار داره؟ چقدر طول میکشه تا ایده اولیتون رو صرفا با «به هم چسبوندن ابزارهای موجود» بسازید؟ متاسفانه در این مورد هم باید بگم که Go بازندست. البته این رو هم باید در نظر داشت که Go زیادی جوانه و خب طبیعتا از بین این همه شرکت بزرگی که برای توسعه به سمتش رفتند، بالاخره از این جهت هم به بلوغ کافی میرسه. اما بحث ما، بحث حال حاضره. در حال حاضر، پایتون از این جهت – به نظر من – بهترین گزینه میتونه باشه. میدونید چرا؟ چون برای هر چیزی که فکرش رو بکنید یک کتابخونه ارائه کرده و واقعا شما نیاز به پیاده سازی منطقی جز منطق خالص کسب و کار خودتون ندارید.
مقیاسپذیری
خب، جایی که Go واقعا حرفی برای گفتن داره و برندهست، در مقیاسپذیریه. سرعت بالای Go باعث میشه با حداقل سختافزار روی مقدار زیادی درخواست و کاربر همزمان پاسخ خوبی بده. در صورتی که مقیاس کردن پایتون یا PHP انقدر راحت نیست. اگر مقیاسپذیری براتون امری به شدت حیاتیه و حس میکنید که میتونید تو مدت زمان کوتاهی ممکنه نیاز به مقیاس بالایی داشته باشید، سمت Go برید.
سهولت استقرار
قبلتر در همین وبلاگ در مورد مهندسین DevOps توضیح داده بودم (لینک) و خب یه حقیقت تلخ در مورد این عزیزان اینه که نیروهای گرانقیمتی هستند. وقتی شما از ابزاری مثل Go یا حتی پایتون برای توسعه محصولتون استفاده کنید، احتمالا بعد مدتی نیاز دارید که برای استقرار و … محصول، از یک مهندس DevOps کمک بگیرید. این نیاز ممکنه از لحظه استقرار MVP با شما باشه تا وقتی که محصولتون رو بازسازی و ریفکتور میکنید. در صورتی که برای مثال یک پروژه Laravel ای رو میتونید به سادگی روی یک هاست سیپنل، میزبانی کنید.
و تیر آخر: زمان توسعه محصول!
در قسمت اول به این موضوع اشاره کردم ولی لازمه که دوباره هم اشاره بشه. چرا که این بخش به بخش کدنویسی و تست (و کلا کارهای برنامهنویسانه) محدود نیست و لازمه که موارد دیگر مثل استراتژی ورود به بازار، ارائه بتاهای عمومی و … هم در نظر بگیرید. متاسفانه Go در این مورد بازندست چرا که ابزارهایی به کاملی و خوبی جنگو، ریلز یا لاراول نداره. تنها راهحلی که بتونید با Go با سرعت زیادی به این مرحله برسید؛ اینه که چند توسعهدهنده حرفهای استخدام کنید که خب هزینههاتون رو شدیدا افزایش میده.
جمعبندی
حالا که این همه مثنوی هفتاد من سرودم، جای داره که یک جمعبندی کلی ارائه بدم از مباحث بالا. اگر موارد بالا رو در نظر گرفتید و دیدید که زبانی مثل Go یا Rust در فاکتورهای بالا برای شما کارآمد و مناسب هستند و انتخاب شخصیتونن و در عین حال، منابع کافی هم براشون دارید؛ خب دیگه پرسش نداره و بهتره هرچه سریعتر کارتون رو شروع کنید. در غیر این صورت، اگر از سر جوزدگی قراره از این ابزارها استفاده کنید، چند بار با خودتون مرور کنید که کدوم یکی از اینها، نیازهای شما رو مرتفع میکنند.
در پایان جا داره بگم که زبان برنامهنویسی صرفا ابزاریه که ما بتونیم باهاش برنامه بسازیم و برنامههای کامپیوتری، پاسخهایی هستند به نیازهای ما. انتخاب ابزار مناسب، امکانسنجی خودش رو نیاز داره و امیدوارم که در این پست؛ تونسته باشم به شما کمی در این امکانسنجی، کمک کرده باشم.
با تشکر از وقتی که گذاشتید و این مطلب رو خوندید. امیدوارم این مطلب براتون مفید واقع شده باشه.
چندی پیش، در مورد پیشنیازهای یادگیری بینایی ماشین در همین وبلاگ نوشته بودم (لینک) و بعد از اون هم در مطلبی در ویرگول، در مورد این که چرا موجودیتی به اسم «جامعه بینایی ماشین» رو راه انداختم (لینک) صحبت کردم. پس از انجام چندین پروژه و تولید چندین محتوا پیرامون این موضوع، امروز در این پست قراره که ایده هایی که شما میتونید در پروژه های بینایی ماشین و پردازش تصویر خودتون به کار بگیرید رو بررسی کنیم.
توجه داشته باشید که در این پست، فرض رو بر این گذاشتیم که شما با هوش مصنوعی، پایتون، بینایی ماشین و … آشنایی لازم و کافی رو دارید و حالا قصد دارید یک پروژه جدی باهاش انجام بدید اما نمیدونید باید چی کار کنید. اگر آشنایی ندارید هم مشکلی نیست، میتونید این مطلب رو صرفا برای ایجاد علاقه و یا رفع کنجکاوی بخونید 😁
ایده های مرتبط با تشخیص چهره
تشخیص چهره، همیشه یکی از پرطرفدارترین شاخههای پردازش تصویر و بینایی ماشین بوده است. چرا که با استفاده از تشخیص چهره، میتوانیم عملیات جالبی انجام دهیم و پروسههای زیادی از یک کار بزرگتر را، خودکار کنیم. همچنین میتوانیم امنیت خانه و محل کار و … را نیز با استفاده از تشخیص چهره تامین کنیم.
در لیست زیر، تعدادی از پروژههای مرتبط با تشخیص چهره رو برای شما فهرست کردهام:
حضور و غیاب مبتنی بر چهره
دوربین امنیتی (به این شکل که وقتی شخص ناشناسی وارد حریم دوربین شد از طریق ایمیل یا SMS و … به شما اطلاع بده)
قفل هوشمند ( به شکلی که اگر شما رو دید در رو باز کنه و در غیر این صورت، یک سیستم مانند دزدگیر یا سیستم امنیت خونه رو راهاندازی کنه)
تشخیص حالت و احساسات چهره
تشخیص خوابآلودگی (مثلا در یک کلاس این پروژه میتونه کاربردی باشه).
همه ایدههای بالا، به سادگی قابل انجام هستند. فقط کافیه که کار با کتابخانهها و تئوری پردازش تصویر رو بلد باشید. شاید دو سه روزه بتونید یکی از این پروژهها رو به ثمر برسونید 😁
ایده های مرتبط با تشخیص کرکتر
تشخیص نوری نویسه یا Optical Character Recognition که به اختصار به اون OCR هم گفته میشه، یکی از شاخههای پرطرفدار دیگر در حوزه بینایی ماشین میتونه به حساب بیاد. پروژههایی که در این حوزه انجام میشن به شدت کاربردی هستند و طبیعیه که در حوزههای مختلفی کاربرد خواهند داشت. در اینجا تعدادی از ایدههایی که میتونید روش کار کنید رو اینجا فهرست کردم:
تشخیص و استخراج شماره پلاک (که پیشتر در موردش نوشتم – لینک)
تشخیص و حل مسائل ریاضی/فیزیک (که این هم پیشتر در مورد نوشتم – لینک)
تشخیص دستخط فارسی
تشخیص خط نستعلیق (و در کل خوشنویسی) فارسی
تشخیص نسخه پزشکی (نکته جالب اینه که در نسخ پزشکی، بسیاری از خطخطیهایی که میبینید در واقع روش مصرف و دوزاژ دارو هستند، که طبق کدگذاری خاصی نوشته میشن).
البته باید این نکته رو هم عرض کنم خدمتتون که دنیای OCR خیلی گستردهست. تقریبا هرجایی که شما با نوشتن سر و کار داشته باشید، میتونید از OCR هم اونجا استفاده کنید. خیلی چیزا اینجا به خلاقیت و نیازهای خودتون برمیگرده. اگر ایده دیگری داشتید، میتونید در بخش نظرات همین مطلب با من به اشتراک بذارید.
ایده های مرتبط با پزشکی
هوش مصنوعی در علم پزشکی، جایگاه خاصی در سالهای اخیر داشته. چرا که همه دانشمندان کامپیوتر و همچنین پزشکی، دریافتند که با استفاده از راهحلهای هوشمند، میتونند به حد قابل توجهی، خطاهای پزشکی رو کاهش بدند. همچنین تحقیقات دارو و واکسن هم به شدت سریعتر میتونن انجام بدند. برای مثال، همین دنیاگیری ویروس کرونا که در سال ۲۰۱۹ آغاز شد و کماکان ادامه داره رو بررسی کنیم، بارها از این که از هوش مصنوعی برای پیدا کردن ترکیبات دارویی موثر بر ویروس استفاده شده، صحبت کردند. همچنین در پروسه ساخت واکسن هم بسیاری از مراحل رو به ماشین سپردند و به هوش ماشینی اعتماد کردند. شاید یکی از دلایلی که واکسن این بیماری انقدر سریع ساخته شد، استفاده از همین راهکارهای هوشمند در تولید بوده.
بینایی ماشین هم استثناء نیست و طبیعتا میتونه خیلی به کمک افراد بیاد. در این بخش، تعداد زیادی از ایدههایی که میتونه به پزشکها در شناخت بهتر مشکلات بیمارهاشون کمک کنه رو فهرست کردم و خب بد نیست اگر شما هم سراغش برید و سعی کنید یکیش رو پیاده کنید (این بخش میتونه برای دانشجویان مهندسی پزشکی و پزشکی؛ بسیار مفید باشه)
تشخیص نوع تومور مغزی (تصویر این بخش، پروژهای که خودم انجام دادم)
تشخیص رتینوپاتی دیابتی در اشخاص مبتلا به دیابت
تشخیص MS و مراحل مختلف اون بر اساس MRI
تشخیص سلولهای سرطانی
تشخیص میزان درگیری ریه در بیماریهای تنفسی (مانند COVID-19)
تشخیص ناهنجاریهای پوستی
تشخیص آسیبهای استخوان
تشخیص آسیبدیدگیها و پوسیدگیهای دندان
طبیعتا اینها، همه کارهایی که میتونیم در حوزه پزشکی با کمک بینایی ماشین و پردازش تصویر انجام بدیم نیستن و این دامنه میتونه به شدت گستردهتر باشه. طبیعیه که گستردگی این دامنه به خلاقیت خودتون و نیازهاتون برمیگرده. همچنین طبیعتا اگر شما دانشجوی مهندسی پزشکی یا رشته پزشکی و رشتههای مرتبط باشید، احتمالا ایدههای بهتری خواهید داشت.
سایر حوزهها
چندین و چند حوزه دیگر هست که خب مثل باقی حوزههای پوشش داده شده در این مطلب، نمیشه ایدههای پروژههای بینایی ماشین و پردازش تصویرشون رو فهرست کرد. به همین خاطر، توضیح اجمالی راجع به هر کدوم میدم تا شما ببینید که کدوم حوزه رو بیشتر دوست خواهید داشت و در کدوم حوزه ممکنه بتونید ایدهپردازی بهتری داشته باشید.
تشخیص حرکت یا Action Detection
این حوزه به طور خاص، میتونه برای کارهایی مثل تشخیص و ترجمه همزمان زبان اشاره (لینک)، تشخیص حرکات ورزشی و یا تشخیص «نیت» افراد بشه. برای مثال، میتونیم سیستمی بسازیم که حرکات بعدی فرد در یک نبرد تن به تن (مثل مسابقه بوکس) رو پیشبینی کنه و به مربیها و نوآموزهای اون رشته اطلاع بده.
خودروهای خودران
خودروهای خودران یا Self-Driving که پیشتر هم ازشون در همین وبلاگ صحبت کرده بودم (لینک) میتونن با استفاده از بینایی ماشین و پردازش تصویر، تابلوهای راهنمایی، رفتار سایر رانندگان، موانع در مسیر و … رو تشخیص بدند. این حوزه البته پیچیدگی زیادی داره اما کار کردن روی بخشهای مختلفش میتونه برای یادگیری جوانب مختلف ماجرا جذاب و جالب و مفید باشه.
مصرف انرژی
حوزه انرژی هم حوزه جالبی میتونه برای پروژههای بینایی ماشین باشه. برای مثال OCR ای که بتونه دیتای کنتور گاز/برق رو به متن تبدیل کنه و اون رو با یک مرکز محاسبه قیمت، چک کنه و قیمت رو به ما اعلام کنه. همچنین میشه عکسهای حرارتی از خانهها و … تهیه کرد و با استفاده از بینایی ماشین دقیقا بررسی کرد که کجاها انرژی بیشتری داره از دست میره و … .
این پروژهها به خودی خود شاید جالب به نظر نرسن اما ترکیبشون با IoT و هوشمندسازی در سطوح دیگر، طبیعتا میتونه جذاب و حتی پولساز هم باشه.
کشاورزی
این هم گفتن نداره، شما کافیه که یک سری عکس هوایی از زمینهای کشاورزی داشته باشید. احتمالا خیلی راحت بتونید سیستمی توسعه بدید که آفات رو شناسایی کنه. همینطور میتونید نوع خاک و … هم از روی این عکسها طبقهبندی کنید و پیشنهاد بدید که چه محصولی در این زمین کشت بشه بهتره. در حوزه مصرف انرژی هم میتونید یکی از پروژهها رو بردارید بیارید اینجا و ازش بهرهبرداری کنید. چی از این بهتر؟
ضمن این که امنیت زمین کشاورزی و گلخانه، بررسی نور و رنگ و … هم میتونن اینجا کاربردی باشند.
جمعبندی مطلب
در این مطلب، ایدههایی که میتونید بعنوان یک پروژه تفریحی یا جدی پیادهسازی کنید رو بررسی کردیم. همچنین این ایدهها، به جز این که میتونن رزومه خوبی برای شما بسازند طبیعتا میتونن پایه یک کسب و کار و یا یک استارتاپ باشند که شانس خوبی برای به پول رسیدن داره. به همین خاطر هم ممنون میشم اگر هر کدوم از این ایدهها رو پیادهسازی کردید در بخش کامنت همین مطلب در موردش بنویسید و به من اطلاع بدید تا ببینم چه کردید.
همچنین لازم به ذکره که اگر دوست دارید مطالب فنی/علمی دیگری از من بخونید، میتونید به ویرگول من هم مراجعه کنید. در پایان هم بابت وقتی که گذاشتید، ازتون تشکر میکنم و امیدوارم در آینده باز هم بتونم در این وبلاگ، مطلب بنویسم.
مدتها پیش، من شروع به نوشتن پیرامون بینایی ماشین و پردازش تصویر کردم (برای مثال، یکی از نتایجی که از این موضوع گرفتم راهاندازی جامعه بینایی ماشین بود) و کم کم تلاشم بر این شد که هوش مصنوعی و یادگیری عمیق و یادگیری ماشین و … هم وارد ماجرا کنم چرا که دونستن OpenCV و به طور کلی بینایی ماشین، چیز خاصی نیست و دانش خاصی به ما اضافه نمیکنه. البته اشتباه نکنید، این که شما یک ابزار خوب مثل OpenCV و کار باهاش رو بلد باشید، خیلی هم خوبه اما کافی نیست.
خلاصه پس از مدتی، شروع کردم به مطالعه الگوریتمهای مختلفی که برای تشخیص اشیا و یا مکانیابی اشیا نوشته شده بودند، اونها رو مطالعه کردم و یکی یکی این ابزارها رو سعی کردم امتحان کنم تا ببینم هرکدوم چطور دارند کار میکنند و … . در این میان با YOLO و مفهومی که داشت، آشنا شدم ولی مشکلاتی سر راه بود که در همین مطلب بهشون اشاره میشه. اما نسخه ۵ یولو، یه جورایی شد رفیق راهم (که خب توضیح دادم چرا دوستش دارم) و در بسیاری از پروژهها مثل حل مسائل ریاضی و همچنین تحلیل مدارات الکتریکی، کمک بسزایی به پیشبرد پروژه کرد.
حالا اگر نوبتی هم باشه، نوبت یک پروژه جدید و باحال دیگره که با YOLOv5 انجام بشه. در اینجا لازمه اشاره کنم که مدلهای هوش مصنوعی صرفا ابزار هستند و گاهی ما ممکنه اصلا نیازی به هوش مصنوعی برای حل مساله نداشته باشیم. مورد بعدی این که ما از ابزار چطور، کجا و چگونه استفاده کنیم خودش امر مهمیه و عموم مقالات مهندسی، پایاننامههای رشتههای مهندسی و …؛ همه در این تلاش هستند که یا این ابزارها را بهینه کنند یا این که روش مناسبی برای استفاده از این ابزارها پیدا کنند.
پروژهای که این بار انجام دادم چه بود؟ این پروژه این بار سامانه تشخیص پلاک خودرو با کمک YOLOv5 است که در نگاه اول، به نظر چیز سادهای میرسه اما در عمل خیلی ساده نیست و در حین پیادهسازی، نیاز داشتم که سادهترش کنم. اما بذارید ایده کلی رو با هم بررسی کنیم. ایده کلی ما این بود که سیستمی داشته باشیم که حضور و غیاب به کمک پلاک خودرو را ممکن کند. حالا این مورد کجاها میتونه استفاده بشه؟ خیلی جاها. پارکینگهای عمومی، جاهایی که خودروها تا ثبت نشده باشند نمیتونن وارد باشن، پلیس راهنمایی و رانندگی و … .
در این پست، با هم به تفصیل به بررسی این پروژه میپردازیم و میبینیم که این پروژه بینایی ماشین چطور انجام شده. سعی کردم که مطلب تا حد خوبی فرمتی مشابه تحقیقات و پایاننامههای دانشگاهی هم داشته باشه تا دوستانی که نیازمند نوشتن چنین مطلبی هستند هم بدون تغییرات زیاد بتونن از مطالب این پست خاص استفاده کنند.
طرح کلی مساله
مساله کلی ما در اینجا اینه که نرمافزاری توسعه بدیم که بتونه نوشته روی پلاک خودروهای ما رو بخونه و اون رو با محتوایی که در یک دیتابیس خاص داریم، تطابق بده. در اینجا ما میتونیم سناریویی فرضی داشته باشیم به این شکل که «فرض کنیم یک پارکینگ داریم که خودروها باید قبل از حضور، پلاکشون رو ثبت کنند و موقع ورود، پلاک خوانده میشه و چنانچه مطابقتی بیش از ۷۰٪ با حداقل یکی از پلاکهای درون دیتابیس پارکینگ داشت؛ مجوز ورود صادر خواهد شد». این سناریوی فرضی به ما کمک میکنه که در ادامه، بهتر پیادهسازی رو انجام بدیم.
پس مشخصا ما نیاز به سیستمی داریم که بتونه تصویر از پلاک دریافت کنه، محتوای متنی تصویر رو استخراج کنه و اون رو با متونی که پیشتر در یک دیتابیس ذخیره کردیم تطابق بده و خروجی مورد نظر ما (مجوز ورود) رو صادر کنه. برای این که بتونیم فرایندی که میخواهیم رو سادهتر کنیم، در اینجا چند مورد لحاظ شده:
محتوای متنی پلاک فقط محدود به اعدادیه که درون پلاک داریم.
برای سادگی بیشتر پروژه، بخش سختافزاری سیستم در نظر گرفته نشده.
برای سادگی باز هم بیشتر، از قسمت دیتابیس و تطابق چشمپوشی کردیم.
در واقع، پیادهسازی پیش روی شما صرفا پیادهسازی از نویسهخوان نوری (OCR) و در حقیقت قسمت مرتبط با بینایی ماشین و YOLOv5 در این پروژه بوده که خود همان هم، بخش زیادی از این پروژه رو شامل میشد.
کارهای پیش تر انجام شده
در این بخش، کارهایی که پیشتر در این زمینه انجام شدند رو با هم بررسی میکنیم. چرا که در بخش انتخاب ابزار احتمالا نیاز به این داشته باشیم که به این قسمت برگردیم و مواردی رو بررسی کنیم. به هرحال در طی جستجوهای انجام شده توسط شخص من، دو پروژه خیلی نظرم رو جلب کردند که در ادامه به معرفی اونها میپردازم.
پلاک خوان دیوار
وبسایت یا اپلیکیشن دیوار برای خیلی از ماها، نام آشناییه. خیلی از افراد هستند که از طریق این اپلیکیشن اقدام به خرید و فروش خودرو هم میکنند و برای تامین امنیت صاحبان خودرو در این پلتفرم، اقدام به طراحی و تولید مدل مشابهی کردند که بهشون کمک کنه تا بتونند پلاکها رو با قالب مناسب وبسایت دیوار، جایگزین کنند تا همه قادر به دیدن پلاک خودروها نباشند. دوستانی که در این پروژه در دیوار همکاری داشتند خوشبختانه مراحل کارشون رو خیلی دقیق و جالب در این پست ویرگولیشون، توضیح دادند و به نظرم بد نیست که همینجا توقف کوچکی کنید و پست این دوستان رو مطالعه کنید؛ سپس برگردید و ادامه این پست رو بخونید.
مراحل اولیه پروژه مورد بحث در همین پست – تلاش برای بازسازی پلاکخوان دیوار
پروژه تشخیص پلاک با پایتون (با استفاده از OpenCV و KNN)
این یکی پروژه هم یکی از پروژههای خوبی در زمینه بینایی ماشین و تشخیص پلاکه که یکی از کاربران آپارات، با پیروی از یک شخص خارجی – که در یوتوب کار مشابهی انجام داده – پیادهسازیش کرده. یک ویدئوی دو ساعت و نیمه که به نظرم ارزش دیدن و فکر کردن داره.
در بخش بعدی، اشاره خواهم کرد که چرا این روش رو اتخاذ نکردم و ترجیح دادم که از YOLOv5 استفاده کنم. برای دیدن این ویدئو، میتونید از این لینک استفاده کنید.
انتخاب ابزار و تکنولوژی
در این بخش، به تفصیل قراره تمامی ابزارهایی که پیش روی ما بود رو بررسی کنیم. در واقع این یکی از روتینهای تحقیقات علمیه که قبل از توضیح کامل ابزاری که استفاده کردیم، توضیح بدیم چرا از یک سری از ابزارها، استفاده نکردیم. این مورد به افرادی که بعد از ما قراره روی اون موضوع کار کنند کمک میکنه تا اول سراغ ابزارهایی که قدیمی شدند یا به هر دلیلی «به درد نخور» هستند نرن و دوم اگر قرار باشه ابزار متفاوتی از ما رو انتخاب کنند، بتونن یکی از همینها رو بررسی کنند (حالا ممکنه اصلا کل بررسی سر به درد نخور بودن ابزار باشه!).
استفاده از Tesseract
تسرکت یکی از نرمافزارهای آزاد مشهور در زمینه OCR محسوب میشه که امتیازات ویژه خودش رو هم داره. برای مثال شاید بشه گفت بزرگترین امتیازش اینه که بدون مشکل روی همه سیستمعاملهای مرسوم دنیا نصب و اجرا میشه و مهم نیست شما مک داشته باشید یا ویندوز یا گنو/لینوکس؛ به سادگی میتونید اجراش کنید و ازش استفاده کنید. مورد بعدی که باعث میشه افراد به سمت تسرکت برن هم اینه که کتابخونهای برای استفاده مستقیم در پایتون داره و این خودش یک امتیاز بزرگه که نرمافزاری که به صورت stand-alone اجرا میشه رو بشه با یک wrapper ساده وارد زبان برنامهنویسی مورد علاقمون کنیم.
در عین حال تسرکت مدعیه که زبانهای مختلفی – من جمله فارسی – رو پشتیبانی میکنه و اینجا میخوایم دلیل عدم استفاده از این ابزار رو دقیقا در همینجا پیدا کنیم. تسرکت، نیاز داره که با فونتهای مختلف آموزش داده بشه و پیدا کردن فونتی مشابه فونتهای مورد استفاده در پلاک خودروهای ایران، کاری تقریبا ناممکنه. البته بعضی از تایپفیسها مثل تایپفیس فونت رویا تقریبا به فونت مورد استفاده در پلاک خودروهای ایران نزدیکه و شاید بشه باهاش کاری کرد. اما این بحث آموزش تسرکت و نتیجه نگرفتن احتمالی باعث خط خوردن تسرکت از لیست شد.
استفاده از KNN
خود کتابخانه OpenCV تابعی برای آموزش یک طبقهبند KNN یا K-Nearest Neighbor ارائه میکنه که در ویدئویی که در بخش قبل لینک دادیم هم استفاده شده. این مورد هم مشکلات خاص خودش رو داشت و از لیست حذف شد. یکی از واضحترین دلایل این بود که ممکن بود این روش خاص، در اعداد شبیه به هم کمی مشکل ایجاد کنه. در کل، علیرغم این که الگوریتم K نزدیکترین همسایه، الگوریتم مورد اطمینانی در یادگیری ماشین کلاسیک محسوب میشه، ریسک خطای مدل نهایی رو هم میتونه بالا ببره.
استفاده از EasyOCR
کتابخانه EasyOCR یکی از محبوبترین کتابخانهها در میان مهندسین بینایی ماشین در دنیاست. یکی از دلایلش اینه که با سرعت خوبی (بخصوص با داشتن GPU) میتونه متون رو تشخیص بده و از همه مهمتر، دور متون مورد نظر ما Bounding Box قرار بده. این کتابخانه هم زبانهای زیادی مثل انگلیسی، آلمانی، نروژی و … رو پشتیبانی میکنه اما نقطه قوتش نسبت به Tesseract اینجاست که در زبانهای فارسی و عربی هم بدون نیاز به استفاده از فونت و …؛ میتونه تشخیص خوبی بده.
با این وجود، مدلی که EasyOCR ازش استفاده میکنه هنوز به خوبی برای زبان فارسی fine-tune نشده و پروژه حال حاضر رو نمیتونه به سرانجام برسونه. به همین دلیل، این ابزار هم از لیست ابزارهای مورد استفاده در پروژه ما، خط میخوره. البته این هم باید اشاره کرد که EasyOCR نرمافزاری آزاده که میشه بهش کمک کرد و بهبودش بخشید (روشش رو اینجا میتونید پیدا کنید).
استفاده از سیستمها و سرویسهای OCR ایرانی
در سالهای اخیر، با توجه به این که افراد زیادی به خوندن کتابها و جزوههای الکترونیکی و اسکنشده روی آوردن، خیلی از شرکتها و گروههای فعال در زمینه متنکاوی و … هم بیکار نبودند و سیستمهای OCR خوبی توسعه دادند که به صورت خاص، برای زبان فارسی کار میکنند.
اما دو مشکل بزرگ اینجا داشتیم. اولین مشکل این که اکثر این سرویسها آنلاین هستند و خیلی از کاربران نهایی این پروژه (مثل یک سازمان دولتی) احتمالا حاضر به این نمیشه که دادههای خودروهاش و کارمندانش رو به یک سرور شخص ثالث ارسال کنه. مشکل دوم هم این بود که اکثر نسخههای آفلاین گرونقیمت هستند. البته شاید بشه مشکل سومی هم اینجا لحاظ کرد و اون اینه که خیلیهاشون امکان این که در یک کد پایتونی بشه ازشون استفاده کرد هم فراهم نمیکنند. پس این گزینه هم کاملا از لیست ما خط خورد.
توسعه CNN اختصاصی
این روش همیشه برای من نقش پلن ب رو داره که اگر مدلی مثل YOLOv5 برای نیازم پاسخگو نبود، سراغش بیام. اما چرا در این پروژه سراغش نرفتم؟ چون که توسعه برای OCR میتونست به شدت زمان، هزینه و انرژی مصرف کنه و حقیقتا چون این پروژه قرار نبود پروژه پولساز باشه یا برای هدفی مثل پایاننامه و … انجام بشه، ارزش این که شبکه عصبی اختصاصی براش توسعه بدیم رو نداشت.
استفاده از YOLOv5
در نهایت، لازم بود که از مدلی مثل YOLOv5 استفاده بشه برای این که بتونیم OCR مخصوص پلاک رو توسعه بدیم. چرا YOLOv5 و چرا سایر نسخههای یولو نه؟ پیشتر این مورد رو به تفصیل توضیح دادم اما توضیح کوتاه ماجرا میشه سهلالوصول بودن نتیجه transfer learning و fine-tuning این مدل خاص. این مدل، یعنی YOLOv5 به سادگی میتونه روی سیستم شخصی من (مکبوک پرو آخر ۲۰۱۹ با سیستم عامل مک) و روی گوگل کولب اجرا بشه. همچنین انتقالش به سایر سیستمها هم راحت انجام میشه و از این نظر، خیالم میتونست راحت باشه.
گذشته از بحث سختافزار و پلتفرم، YOLOv5 به شدت سریع و با دقته، و این مورد میتونه خودش یک امتیاز مثبت بزرگ برای استفاده از این مدل خاص در کاری مثل پروژه خواندن پلاک با YOLOv5 باشه!
جمعآوری و پیشپردازش داده مورد نیاز
بعد از این که ابزارها و تکنولوژیهای مورد نیازمون رو پیدا کردیم، لازم بود تا دادههای مورد نیاز پروژه هم پیدا کنیم. اولین و سادهترین راه (مطابق این مطلب) این بود که خودمون دست به کار شیم و از پلاک خودروها، عکاسی کنیم. اما این قضیه میتونه دردسرساز بشه چرا که خیلیها خوششان نمیاد که کسی از ماشینشون عکاسی کنه. به همین دلیل، در اینترنت جستجو کردم و به دیتاست مورد استفاده در این مطلب رسیدم. در این دیتاست ۳۱۷ عکس از پلاک خودروهای ایران وجود داره که این خودش عالیه! یک حجم خوب از پلاک خودرو که میدونیم دردسری هم برای ما ایجاد نمیکنه.
پس از این که دادههای مورد نظر خریداری و دانلود شد، نوبت به لیبل زدن بود. لیبلهای ما اعداد ۰ تا ۹ بودند و گذشته از اون، برای این که داده تستی کافی داشته باشیم و مراحل پیادهسازی سریعتر پیش بره، فقط ۷۵ تا عکس رو با کمک labelImg لیبل کردیم.
پیادهسازی پروژه
پس از این که ایده کلی، ابزار و داده برچسبزدهشده رو داشتیم، نوبتی هم باشه نوبت آموزش دادن YOLOv5 برای اینه که کار ما رو به درستی انجام بده. حقیقتا، YOLOv5 و ابزارهای مشابه، خودشون یک دور آموزش دیدند و ما فقط به قولی اونها رو fine-tune میکنیم که کاری که ما بخواهیم رو انجام بدن (در نظر بگیرید که ما در دوران ابتدایی و راهنمایی خیلی چیزا رو یاد گرفتیم، در دبیرستان رفتیم سراغ ریاضی و تجربی و اختصاصی اونها رو یاد گرفتیم و بعد در دانشگاه مثلا مهندسی خوندیم که یک فرم خاصتر از ریاضیه. دقیقا مشابه همین فرایند اینجا برای آموزش YOLOv5 هم داره صورت میگیره) و الان فقط کافیه که دیتا و کدهای مورد نیازمون رو در یک سیستم مناسب پروژههای هوش مصنوعی بارگذاری کنیم و سپس مراحل آموزش رو طی کنیم.
دادههای ما روی Google Colab آپلود شدند چرا که آموزش YOLOv5 نیازمند داشتن GPU است. بعد از اون، آموزش به این صورت شکل گرفت که هفتصد و پنجاه epoch (یا نسل) طول کشید، سایز batch ما ۳۲ بود، اندازه تصویر به ۴۱۶ د ۴۱۶ پیکسل تغییر کرد (اسکریپتی که برای آموزش YOLOv5 توسط تیم Ultralytics ارائه شده خودش امکان تغییر سایز رو فراهم کرده) و مدل پایه مورد استفاده yolov5m بود که با ۲۱.۲ میلیون پارامتر آموزش داده شده. پس از حدود ۳ ساعت و ۴۰ دقیقه، مدل ما آماده بود و نیاز داشتیم که تستش کنیم.
نتایج آزمایش
نتیجه آزمایش روی دیتاست آموزش
همین عکس که در ابتدای مطلب هم ازش استفاده شده، عکسیه که در دیتاست آموزشی موجود بود و درستی کار مدل رو تایید میکرد. جدول زیر هم میزان دقت رو به درستی به ما نشون میده:
نتیجه آزمایش روی دیتاست آزمایشی
در جدول زیر هم به صورت مرتب شده میتونیم میزان دقت این مدل رو هم ببینیم. همچنین با یک تابع ساده، پلاک رو به شکل درستش (مبتنی بر ستون xmin) مرتب کردیم تا با پلاک اصلی تطبیق بدیم:
جمعبندی و نتیجهگیری
در اینجا لازمه که پروسههایی که طی شده رو یک بار دیگه بررسی کنیم تا به یک جمعبندی روی پروژه برسیم:
ابتدا تصمیم گرفتیم سیستمی طراحی کنیم که حضور و غیاب یا رفت و آمد رو بتونه مبتنی بر پلاک خودروهای حاضر در یک محل خاص، بررسی کنه.
سپس تصمیم اولیه رو با حذف پروسه دیزاین سختافزاری و همچنین حذف حروف مورد استفاده در پلاک سادهسازی کردیم.
پس از سادهسازی، ابزارهای متنوعی رو مطالعه کردیم و سپس YOLOv5 رو به عنوان ابزار اصلی خودمون انتخاب کردیم.
دیتاستی رو تهیه کردیم و برچسب زدیم.
مدل YOLOv5 رو مطابق نیاز و با دادههای خودمون آموزش دادیم.
در کل، این پروسه گرچه پروسه نسبتا وقتگیر و سختی بود، اما نتیجه به دست آمده واقعا راضیکننده و خوبه. در حال حاضر پروژه ما در حالی قرار داره که میتونه به سادگی با ارتباط با یک سیستم سختافزاری، کاری که براش در نظر گرفته شده رو انجام بده. البته هنوز ضعفهایی متوجه این پروژه هست که در بخش بعدی در موردشون بحث خواهیم کرد.
کارهای آینده
در این قسمت، کارهایی که در آینده میشه برای این پروژه انجام داد رو با هم یک بررسی اجمالی میکنیم:
توسعه سیستم برای خواندن حروف وسط پلاک (چالشهای خاصی در این زمینه وجود داره، مثلا حرف ژ در پلاک خودرو معمولا به شکل ویلچر چاپ میشه)
توسعه سیستم برای خواندن پلاکهای غیرشخصی (پلاکهای عمومی و تاکسی عموما زرد، پلاک وزارت دفاع آبی، پلاک سپاه و نیروی انتظامی سبز پررنگ، ارتش سبز خاکی، دیپلماتیک آبی آسمانی و پلاک خودروهای دولتی قرمز هستند)
توسعه سیستم برای تشخیص و خواندن پلاکهای منطقه آزاد
توسعه سیستم برای تشخیص و خواندن پلاکهای گذر موقت
توسعه سیستم سختافزاری و قرار دادن مدلهای هوش مصنوعی در سختافزار مناسب
مجوز نشر
این پست وبلاگ، تحت پروانه مستندات آزاد گنو یا GNU Free Document License منتشر شده و بازنشر و استفاده از محتویاتش کاملا آزاده. فقط توجه لازم داشته باشید که دیتاستی که برای آموزش استفاده شده آزاد نیست و این آزادی در استفاده شامل بخشهایی از این مطلب میشه که مسولیتش با منه (به طور کلی هرچی که شما در این پست خوندید)
سخن آخر
این پست برخلاف پستهای دیگر این وبلاگ به شدت طولانی شد و از بابت این که وقت زیادی برای خوندنش گذاشتید، واقعا از شما متشکرم. در پایان جا داره از شما دعوت کنم که به ویرگول من هم سر بزنید تا اونجا موارد فنی و تجربیات دیگر من رو بخونید. همچنین، اگر این مطلب برای شما مفید بود کافیه که روی تصویر زیر کلیک کنید و من رو به یک فنجان قهوه به انتخاب خودتون مهمان کنید 🙂
دقیقا دو هفته پیش، در نسخه انگلیسی وبلاگ در مورد YOLOv5 نوشتم (لینک) و توضیح دادم که چرا این مدل هوش مصنوعی برای تشخیص اشیاء رو دوست دارم (و حتی چرا شما باید دوستش داشته باشید) و خب طبیعتا دوست داشتم یک پروژه خیلی خیلی ساده و در عین حال باحال هم با این مدل انجام بدم.
ایدههای زیادی در سر داشتم. برای مثال ایده بازی Red Light – Green Light که در سریال اسکوییدگیم همه دیدیم. اما این ایده علیرغم خوب بودنش، آنچنان کاربردی نبود. پس تصمیم من برآن شد که یک نرمافزار دیگر توسعه بدم. نرمافزاری که هم چالش داشته باشه، هم در نهایت یک کاربرد درست ازش بشه درآورد.
نمیدونم شما یادتونه یا نه، اما نرمافزار سیمبولب، دروانی خیلی خاص و معروف شد. به همین خاطر، تصمیم من هم این شد که سیمبولب رو دوباره بسازم و بعد از این که نتایج مورد نظرم رو گرفتم در موردش وبلاگ بنویسم. پس این شما و این ماجرایی که من داشتم تا این نرمافزار رو بسازم.
گام اول: طرح مساله
در هر پروژهای، اولین گام اینه که مطرح کنیم چه مشکلی رو باید حل کنیم. یا به قول دنیل کوهن Look for the pain. خب دردی که ما اینجا به دنبال حل کردنش بودیم، چی بود؟ این که بسیاری از دانشآموزا و دانشجوها سر ریاضی عمومی یا Calculus مشکل دارند. این مشکل ریشهش کجاست؟ برای من شخصا مهم نیست که این ریشه رو بررسی کنم (البته به معنای این نیست که نظری در موردش ندارم، اما از حوصله این مطلب خارجه).
حالا درد این که بسیاری از دانشجوها و دانشآموزها مشکل دارند، چطور میشه براشون یک مسکن خوب تجویز کرد؟ بعنوان یک مهندس هوش مصنوعی، یا بهتر بگم مهندس بینایی ماشین در ذهنم این ایده چرخید و اون این بود که:
یک نرمافزار هوش مصنوعی وجود داشته باشه که از روی عکس مساله، پاسخ نهایی یا راهحل رو به افراد بده.
و این پروژه، در نظر پروژه بسیار بسیار بزرگی بود اما در نهایت، پروژه سادهای شد. در ادامه، در راهی که طی شد توضیح خواهم داد.
گام دوم: انتخاب ابزار
گام دوم برای من، انتخاب ابزار بود. اول از همه میخواستم برم سراغ OCR های آماده برای تشخیص مسائل پارامتری مثل x و y و … . اما بعد دیدم که اینجا علاوه بر حروف و اعداد، نشانهها هم هستند. ضمن این که به شکلی باید توان و … هم تشخیص داد. پس کمی پروژه رو نگه داشتم تا به ابزارها فکر کنم.
بعد از مدتی تحقیق و تفحص، به دارکنت رسیدم که برای ترین کردن YOLOv3 و YOLOv4 استفاده میشه و خب دارکنت مشکلات زیادی هم با خودش به همراه داره. برای مثال کاملا در سیپلاسپلاس نوشته شده و روی سیستمهای مختلف باید از نو کامپایل بشه. با CPU درست کار نمیکنه. کامپایل کردنش روی مک یا ویندوز دردسره و انتقال دادنش به Google Colab هم میتونه تا حد زیادی مشکلساز بشه.
بعد از اون الگوریتم YOLOv5 رو کشف کردم. تقریبا همه مراحل کاملا پایتونی پیش میرفت و این عالی بود. کم کم دیدم که میشه بعد از ترین کردن قضیه، از pytorch هم استفاده کرد و اشیاء رو تشخیص داد و از اون بهتر این بود که در تشخیص اشیاء، میشد خروجی pandas هم گرفت که مختصات شیء مورد نظر به همراه لیبلش در اون data frame خاص موجود بودند. پس به این شکل تشخیص این که ما با چه چیزی روبرو هستیم هم سادهتر از گذشته میشد.
وقتی این ابزار رو با چند چیز مختلف تست کردم، نوبت این رسید که در این پروژه حتما ازش استفاده کنم. اما این تمام ماجرا نیست. دقیقا وقتی که سمت OCR ماجرا هندل میشد، یک بحث خیلی مهم میموند. بحث این که چطوری باید مساله حل بشه؟ برای حل مساله هم از Wolfram Alpha گفتم کمک میگیرم.
خب حالا نوبتی هم باشه، نوبت اینه که دادههای مورد نیاز رو جمع کنیم. قبلتر در مورد راههایی که شما میتونید برای جمعآوری داده استفاده کنید، صحبت کردم و میتونید از اینجا بخونیدش.
نمونه دادههای استفاده شده در این پروژه
گام سوم: جمعآوری داده
برای جمعآوری دادهها، نیازمند این بودم که روی چند سطح مختلف (وایتبرد، کاغذ A4 و همچنین کاغذ خطدار) و با چند دستخط مختلف، مسائل ریاضی رو بنویسم. بعد از نوشتن مسائل ریاضی، از دوستانم خواهش کردم که روی صفحات مختلف و همچنین وایتبرد، مسائل ریاضی رو بنویسند.
بعد از این که مسائل ریاضی رو روی این سطوح و با دستخطهای مختلف داشتم، نوبت عکاسی ازشون بود. از هر بار نوشتن، چندین عکس از چند زاویه گرفتم. چرا که زوایای مختلف باعث میشن توزیع نور هم در تصاویر یکسان نباشه و این خودش یک مرحله data augmentation رو برای من کاهش میداد.
حالا یه حجم زیادی داده دارم، باید بعدش چی کار کنم؟ پاسخ سادهست. الان زمانیه که ما وارد مرحله پیشپردازش داده میشیم.
گام چهارم: پیشپردازش داده
بعد از این که ما دادههای مورد نیاز خودمون رو جمع کردیم، نیازمند اینیم که داده رو پیشپردازش کنیم. به طور کلی، پیشپردازش داده به پروسهای گفته میشه که در اون قراره داده ها تمیز بشن، تغییر کنند (یا به قولی data augmentation رخ بده)، برچسب زده بشن و دادههای غیرلازم (یا همون نویز) دور ریخته بشه.
اولین مرحله برای من اینجا، تکه تکه کردن عکس بود. شاید فکر کنید که برای تکه تکه کردن عکس، از ابزار خاصی استفاده کردم یا کدی زدم. باید بگم که خیر، ابزارم دقیقا ادوبی فتوشاپ و ابزار Slice بود. بعدش با قابلیت save for web آمدم و عکسهای قطعهقطعه شده رو ذخیره کردم. پس از ذخیره نهایی عکسها، نیاز بود که عکسها برچسب زده بشن.
برچسبها، در مرحله آموزش مدل، به ما کمک میکنند که اشیاء رو در تصاویر پیدا کنیم. این برچسبها در مراحل بعدتر به کمک ما میان تا بتونیم مسائل یافت شده رو به ولفرامآلفا بدیم تا برامون حلش کنه. پس لازم بود که این اتفاقات بیفته.
گام پنجم: آموزش مدل YOLOv5
و اما گام یکی مونده به آخر دقیقا این بود که مدل آموزش داده بشه. آموزش این مدل با pytorch به شدت سرراست و راحته و کلش اجرا کردن یک دستور در ترمیناله. باز با این حال، مشکلات عدیدهای داشتم. برای مثال روی لپتاپ شخصی چون GPU مناسب نداشتم، آموزش به شدت طولانی میشد. آموزش رو به Google Colab منتقل کردم و چون پلن رایگان داشتم، اونجا هم یک سری داستان جدیدتر پیش آمد. اما بهرحال هرطور که شد، مدل آموزش داده شد و نتایج خوبی هم ازش گرفتم.
در مورد آموزش مدل و نحوه کار اون به زودی محتوای آموزشی جدیدی تولید خواهد شد که به تفصیل در اون توضیح میدم چطور میتونید YOLOv5 رو خودتون آموزش بدید و باهاش کار کنید. در حال حاضر، توضیح مراحل آموزش تا حد زیادی از حوصله این پست وبلاگ خارجه.
و گام نهایی: آزمایش مدل و نوشتن رابط ولفرام آلفا
پس از این که مدل آموزش داده شد، نیاز بود چندین خط کد پایتون نوشته شه برای چند منظور. اول این که وزنهایی که لازم بود از مدل آموزشدادهشده، لود کنه. دوم این که یک عکس رو از ورودی بگیره و مراحل inference رو روش انجام بده و در نهایت، اگر کاربرخواست اون رو بفرسته به ولفرام آلفا و مرورگر رو براش باز کنه.
برای این مرحله، برخلاف باقی مراحل وقت زیادی نذاشتم ولی با این حال کدش (بدون وزنها) در گیتهاب شخصی من موجوده و میتونید نگاهی بندازید. البته که به زودی گیتهاب بروزرسانی میشه و شما قادر خواهید بود که وزنها رو هم دانلود کنید. اما فعلا وزنها در دسترس نیستند.
در نهایت هم برای این که عملکرد قضیه رو ببینید، این ویدئو کوتاه رو میتونید تماشا کنید که هم inference رو تست میکنیم هم حل مساله با ولفرام رو:
جمعبندی و مشکلات این نرمافزار
این پروژه به عنوان یک پروژه تفریحی، واقعا تفریح خوب و سالمی بود و کلی یادگیری برای من داشت. یادگیری دقیقتر و عمیقتر YOLOv5، یادگیری دقیقتر و عمیقتر PyTorch و از همه مهمتر درگیر شدن با چند مساله و به قولی، دردهای دنیای واقعی. از نتیجه کاملا راضی بودم و هستم، اما فکر نکنم در آینده این پروژه خیلی برام راضیکننده باشه.
احتمالا بعد از مدتی به این پروژه برگردم و بزرگترین مشکلش – یعنی شباهت زیاد ورودیها به هم – رو طور دیگری هندل کنم. برای این که ببینیم یه چیزی در پوزیشن توان یه چیز دیگه قرار گرفته یه چارهای بیاندیشم و … . خلاصه که راه برای بهبودش زیاده و این بهبودها رو شخصا پیگیر هستم که در این پروژه اعمال کنم. شاید هم لازم باشه داده ورودی رو افزایش داد یا حتی مدل مورد استفاده رو عوض کرد.
در نهایت، از شما بابت وقتی که برای خوندن این مطلب گذاشتید، ممنونم. امیدوارم که این مطلب مفید واقع شده باشه و به دردتون خورده باشه. ضمن این که اگر به این تیپ مسائل و مطالب علاقمند هستید، میتونید من رو در ویرگول هم دنبال کنید و اونجا هم مطالبم رو بخونید. اگرچه در ویرگول عمده مطالبم مرتبط با بیزنس، موفقیت و ایناست.
در نهایت از شما خواهش میکنم که اگر این مطلب براتون مفید بود، یک قهوه به انتخاب خودتون مهمانم کنید تا موقع نوشیدن قهوه به یادتون باشم و از این دست مطالب، بیشتر تولید کنم.
چندین روز پیش، شخصی در لینکدین خبری از ساخته شدن یک فراجستجوگر داده بود که به شخصه برای من موضوع جالبی بوده همیشه. منتها طبق عادات مالوف هموطنانمون، بزرگ حرف زدن و زیادی مبالغهکردن هم میشد در اون حرفها دید. چیزی که ساخته شده بود اینطور توضیح داده شده بود که:
فراجستجوگر ساخته شده توسط تیمی از بهترین متخصصان که در یک دانشگاه خاص درس خواندند (که خب همین جملات، بدون توجه به اسم دانشگاه و موسسه و … معمولا پرچم قرمزی در بحث تولیدات ملی و بومیه) به این شکل کار میکنه که نتایج جستجو رو از وبسایتهای معروف به موتور جست و جو مانند گوگل، داکداکگو، بینگ و … برمیگردونه و رد پای شما رو از جست و جو حذف میکنه.
وقتی این رو خوندم، فهمیدم که با یک فراجستجوگر یا metasearch engine روبرو هستیم و خب گفتم بد نیست که با هم یکی بسازیم. قبل از هرچیزی، اگر نمیدونید فراجستجوگر چیه، میتونید به اینجا مراجعه کنید و تعریفش رو بخونید. برای ادامه دادن به مطالعه این مطلب هم لازمه که کمی لینوکس و مدیریت سیستم بلد باشید.
آشنایی با searx
خب searx یک نرمافزار آزاده که هدفش، بهبود تجربه جست و جوی افراد در اینترنته. این نرمافزار، به دو صورت قابل دسترسیه. اول این که تعدادی نمونه عمومی داره (لینک نمونههای عمومی در اینجا قرار گرفته) و هم به صورت «خودمیزبان» یا همون self-hosted. متد خودمیزبان یعنی شما به عنوان کاربر، میتونید به صورت رایگان یا با پرداخت پول (بسته به مدل کسب و کار و توسعه اون پروژه خاص)، اون نرمافزار رو روی هاست یا سرور مورد نظر خودتون نصب کنید.
در این آموزش، قراره با کمک یک سرور لینوکسی، یک زیردامنه، یک کارساز وب و داکر؛ یک فراجستجوگر ساده رو به کمک هم بیاریم بالا. به این شکل میتونیم هم یک نمونه عمومی عرضه کنیم، هم این که دیتای کمتری در اختیار شرکتهایی مثل گوگل یا مایکروسافت بذاریم.
ساخت فراجستجوگر
برای ساخت فراجستجوگر خودمون، نیاز به موارد زیر داریم:
سرور لینوکسی. من شخصا از اوبونتو ۱۸.۰۴ استفاده کردم. برای پردازش بهتر نتایج و نخوردن به مشکل تحریم و …؛ بهتره که سرور داخل ایران هم نباشه. به همین خاطر، من از سرور هلند استفاده کردم (کشور محل قرارگیری سرور، کاملا به خودتون بستگی داره).
یک دامنه یا زیردامنه. برای این پروژه من از searx[dot]haghiri75[dot]com استفاده کردم.
کمی آشنایی به کارهای سروری. اگر آشنایی خاصی ندارید هم مهم نیست! در حد لزوم در این مطلب یاد میگیرید 😁
آمادهسازی سرور
وقتی سرور رو از ارائهدهنده سرور تحویل گرفتیم (با فرض اوبونتو/دبیان بودنش) نیازه تا اول لیست بستههای اون رو کمی به روز کنیم:
sudo apt update
و اگر لازم شد، کل سیستمعامل هم یک بار بهروز میکنیم:
sudo apt full-upgrade
بعد از این که این اتفاقات رخ داد، یک دور سرور رو ریبوت میکنیم و پس از بوت شدن مجدد و اتصال به سرور، چند بسته نصب میکنیم:
nginx: این بسته، وبسرور یا همون کارساز وب ماست. چیزی که باعث میشه ما بتونیم بدون مشکل، یک وبسایت یا نرمافزار تحت وب رو استفاده کنیم.
python3-certbot-nginx: از این بسته استفاده خواهیم کرد تا یک گواهی SSL برای وبسایت خودمون بگیریم.
docker.io: داکر یک سیستم کانتینرییزشنه. در واقع نرمافزارها رو داخل بستههای کوچولو قرار میده و همه ملزوماتشون اونجاست. فقط تنها موردی که داره، اینه که از هسته سیستم عامل استفاده میکنه برای مدیریت فرایندها (در واقع تفاوتش با ماشین مجازی همینه).
حالا ما سرور رو آماده کردیم. گام بعدی چیه؟
آمادهسازی دامنه
برای آمادهسازی دامنه، کافیه که یک رکورد A با IP سرور مورد نظر ایجاد کنید. البته در بعضی موارد از CNAME هم میشه استفاده کرد اما اینجا چون سرور از وبسایت جدا بود، یک A تعریف شد. بعد از این که رکورد رو تعریف کردیم، باید ۵ تا ۱۰ دقیقه صبر کنیم تا عموم DNS Server های اینترنت، بشناسنمون. بعدش میتونیم به کارمون ادامه بدیم.
حالا ۱۰ دقیقه گذشت و یک قهوه هم خوردیم و آمادهایم که مرحله بعدی رو انجام بدیم.
دریافت گواهی SSL
خب دریافت گواهی SSL هم بسیار سادهست. کافیه این دستور رو در سرور اجرا کنید (و دامنه من رو با دامنه خودتون عوض کنید):
sudo certbot -d searx.haghiri75.com --nginx
در این مرحله شما باید آدرس ایمیلتون رو وارد کنید و به چند سوال هم پاسخ بدید. در کل همهچیز با یک wizard اتفاق میفته و نیازی نیست که زحمت زیادی بکشید. فقط یک نکته مهم رو اینجا باید بهش دقت کنیم. اون نکته اینه که certbot اینجا خودش nginx رو استارت میزنه. در مرحله بعدی، نیاز داریم که به این مهم توجه کنیم.
راهاندازی داکر و نصب فراجستجوگر
خب اول از همه کاربر خودمون (که در اینجا فرض میگیریم نام کاربریش هم Ubuntu ئه) رو به گروه داکر اضافه میکنیم:
sudo usermod -aG docker ubuntu
بعدش کافیه یک بار از نشست SSH خارج شیم و دوباره به سرور SSH بزنیم. دقت داشته باشید که این بخش الزامی نیست؛ ولی اگر شما این کار رو نکنید بعدا در استفاده از داکر، نیازمند دسترسی ریشه خواهید بود. نگران دسترسی ریشه هم نباشید چون با sudo قابل حله.
بعد از این مورد، ایمیج searx رو از رجیستری داکر دریافت میکنیم:
docker pull searx/searx
خب در حال حاضر، اتفاق خاصی میافته؟ خیر. فقط تصویری که searx روی اون نصب شده، روی سرور ما دانلود شده.
بعد از اون، نیازداریم که یک کانتینر براش بسازیم. برای این، مراحل زیر رو طی میکنیم:
mkdir searx
cd searx
docker run --rm -d -v ${PWD}/searx:/etc/searx -p 8080:8080 -e BASE_URL=http://localhost:8080/ searx/searx
خب تبریک به شما، الان شما یک فراجستجوگر دارید.
اما صبر کنید! هنوز نمیتونیم بهش دسترسی پیدا کنیم. پس چه کنیم؟
پراکسی معکوس برای دسترسی به محتوا
خب اینجا نیاز داریم که از پراکسی معکوس استفاده کنیم. انجینکس علاوه بر این که وبسروره، پراکسی معکوس هم هست و خیلی از ما عمدتا از قابلیت پراکسی معکوسش برای اجرای نرمافزارهای تحت وبمون استفاده میکنیم. مثل همین آموزش دپلوی کردن یک پروژه ریلز نوشته بودم (لینک). دونستن این که پراکسی معکوس چیه و چی کار میکنه، از ملزومات پایهای مدیریت سیستم و همچنین دواپس و CI/CD محسوب میشه (جهت اطلاعات بیشتر این پست رو بخونید).
پس اگر میخواهید در آینده مهندس DevOps بشید، شاید بتونید این مطلب رو فرصتی برای تمرین یکی از مواردش قرار بدید. فکر کنم زیاد صحبت کردیم. بریم سر اصل مطلب. برای این که بتونیم از پراکسی معکوس استفاده کنیم، کافیه که اول با ادیتور دلخواهمون، فایل پیکربندی رو باز کنیم:
sudo nano /etc/nginx/sites-enabled/default
و سپس دنبال دامینمون بگردیم (در نانو با ctrl + W میشه). بعد از این که دامینمون رو پیدا کردیم کافیه بخش location / رو پیدا کنیم (معمولا دو سه خط پایینتر از دامین و تنظیماتشه) و سپس به این شکل درش بیاریم:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
proxy_pass http://localhost:8080;
}
و بعدش هم کافیه که دستور زیر رو اجرا کنیم تا انجینکس ریستارت بشه:
sudo systemctl restart nginx
استفاده از فراجستجوگر شخصی
سخن آخر
نرمافزار searx مثل هر نرمافزار متنباز و آزاد دیگری، قابلیت شخصیسازی داره و همین موضوع که با زبان پایتون نوشته شده هم نشون میده که شخصیسازیش احتمالا از چیزی که فکر میکنیم، سادهتره. به همین خاطر میتونیم به سادگی این نرمافزار رو تغییر بدیم که مطابق میل خودمون کار کنه و طبیعتا آموزشش هم در اینترنت وجود داره.
موضوع بعدی اینه که فراجستجوگرها، علاوه بر این که میتونن در حفظ حریم شخصی و … موثر باشند، میتونن کاملا بیزنسی هم کار کنند. مثلا هرکلید واژهای که سرچ کنید رو صرفا در موضوع خاصی دنبالش بگردند. مثلا شما اگر سرچ کنید «سیبزمینی» فقط در وبسایتهایی که وبینار میزبانی میکنند دنبالش بگرده. وقتی سرچ میکنید «قشم» فقط در وبسایتهای گردشگری دنبالش بگرده و الی آخر.
در این مطلب قصد داشتم این موضوع رو نشونتون بدم که داشتن یک موتور جست و جوی امن، اونقدرا که فکر میکنید سخت نیست و با کمک نرمافزارهای آزاد، به سادگی میتونید یکی رو خودتون بسازید. در پایان مطلب، جا داره از شما بابت خوندن این مطلب تشکر کنم. همچنین، ممنون میشم مطالب و خطخطیهای من رو در ویرگول هم بخونید و نظر بدید 🙂
در پست پیشین، یعنی قسمت اول داستان برنامهنویس شدنم (لینک) از زمانی که شروع به خوندن کتابهای ویژوال بیسیک کردم تا زمانی که پروژه جبیر رو راه انداختم رو به تفصیل توضیح دادم. فکر میکنم داستان برنامهنویس شدن من، داستان جالبی برای خیلی از دوستانی که وبلاگم رو میخونن بوده و به همین دلیل، تصمیم گرفتم که قسمت دومش هم حتما بنویسم.
همونطوری که در قسمت قبلی قولش رو داده بودم، قراره که در این قسمت از بعد از پروژه جبیر تا زمانی که وارد بازار کار شدم رو توضیح بدم و بگم چی شد که اینطوری شد. در مورد مسیرهای شغلی قبلتر توضیح دادم (مثلا در پست چگونه توزیع لینوکس بسازیم و یا پست چگونه بازیساز شویم) همینطور حتی ابزارها و وسایلی که در مسیر شغلهای مختلف طراحی و تولید کردم (مثل صداگذاری روی بازی کامپیوتری) هم در این وبلاگ پیشتر توضیح دادم. فلذا در این مطلب، اصلا و ابدا به مسیرهای شغلی اشاره نخواهم کرد.
ورود به دانشگاه
در طی این سالها، یعنی از حدود ۹۱ تا ۹۳ راههای زیادی رو رفتم که سرویسها و نرمافزارهای خاصی رو طراحی کنم و خب دروغ چرا، تا حد زیادی هم رویای استیو جابز یا زاکربرگ شدن هم در سر داشتم و خب کارهای مختلفی مثل ایجاد انجمنهای اینترنتی مختلف (ایرانبیاسدی، ایرانهکینتاش و …) گرفته تا برپا کردن شبکههای اجتماعی و نرمافزارهای آنلاین دیگر (اکسوال، نکستکلود و …) رو انجام میدادم. راستش این راهها من رو به قول خارجیها Satisfy نمیکرد و همچنان دنبال این بودم که یک سیستم عامل خوب بسازم!
خلاصه شد سال ۹۲ و ما از شهر بندرعباس به تهران برگشتیم. اون سال، سال پیشدانشگاهی من بود (و بد نیست این داستانکم رو هم پیرامونش بخونید) و اون سال، یک تصمیم بزرگ هم گرفتم. تصمیمم این شد که جبیر به جای این که مبتنی بر اوبونتو (یک توزیع از گنو/لینوکس)، یک نسخه شخصیسازیشده از FreeBSD باشه. از همین رو، شروع کردم به رفتن به IRC های مختلف، سوال پرسیدن و مستندات خوندن. بعد از چندین ماه مطالعه، وضعیت اینترنت خونه و خودم تا حد خوبی پایدار شد و بعد شروع کردم به انجام تغییرات روی کد FreeBSD.
بعد از مدتی، پروژه جبیر تا حد خوبی پیش رفت و گذشت و گذشت و من کنکور دادم (داستانی از کنکور هم اینجا نوشتم) و وقتی نتایج اومد، فهمیدم که در دانشگاه آزاد اسلامی واحد تهران مرکز در رشته مهندسی کامپیوتر و گرایش سختافزار قبول شدم.
شرکت در لاگها و رویدادها و آخر و عاقبت پروژه جبیر
حضور در تهران و دانشجو شدن، به من کمک کرد که وارد جامعه بشم و در رویدادهای نرمافزار آزاد و متنباز و سایر رویدادها (مثل PyCon و …) شرکت کنم. اولین رویدادی که شرکت کردم، رویدادی بود به اسم «جامعه رایانش ابری آزاد». در اون رویداد با KVM و Docker آشنا شدم و تا حد زیادی هم دانشم در زمینه Containerها و مجازیسازی تا حد خوبی بالا رفت.
در حاشیه شرکت در این رویدادها، بسیاری از افرادی که از انجمن اوبونتو و یا تکنوتاکس یا لینوکسریویو میشناختم رو حضوری دیدم و باهاشون آشنا شدم و حتی رفاقتهایی شکل گرفت. پس از مدتی، در بحثی دوستانه، تصمیم بر آن شد که پروژه جبیر کلا منحل بشه و پروژهای به این بزرگی که نیازمند دانش فنی بالا، پول زیاد و همچنین حوصله فراوونه، به زمانی موکول شه که بتونم از پس حداقل یک موردش بربیام. فلذا پروژه جبیر اعلام شد که دیگه قرار نیست ادامه پیدا کنه.
اگر دوست دارید ببینید که پروژه جبیر چه شکلی بوده، میتونید این لینک مربوط به وب آرکایو رو هم ببینید: لینک. در ادامه، بنا به دلایلی (که در ادامه این مطلب بهش میپردازیم) تصمیم شد که پروژه جبیر بیشتر روی فاز سختافزاری باشه و چند مطلب هم در موردش حتی نوشتم(لینک).
یادگیری روبی، ورود به حوزه سختافزار و دیگر هیچ!
مهرماه ۹۳ بود که من خیلی جدی تصمیم گرفتم حداقل یک زبان برای توسعه وب رو جدی یاد بگیرم. قبلترش، کتاب «از این پس پایتون» رو خونده بودم و به همین خاطر هم کمی با پایتون و فلسک آشنا بودم. دوستی یک کتاب جنگو هم برای من ارسال کرد. اما در همون هنگام در بحثی در IRC که دقیق یادم نیست مربوط به occc بود یا لاگ کرج، دوستی به من پیشنهاد کرد که روبی و روبیآنریلز رو یاد بگیرم. در ادامهش، توصیه کرد که حتما با دیتابیسها آشنا شم و کمی هم مهندسی نرمافزار یاد بگیرم.
من هم این توصیه رو عملی کردم و شروع کردم به خوندن روبی. شاید باورتون نشه ولی از اونجایی که دیدم زبون روبی، خیلی در ایران زبون روتینی نیست و خیلیها باهاش غریبهند، تصمیم گرفتم دانش خودم رو در قالب یک کتاب الکترونیکی دربیارم و خب نتیجه پس از مدت نسبتا طولانی شد کتاب آموزش روبی که به رایگان قابل دانلوده.
خب همونطوری که ابتدای متن گفتم، من گرایش سختافزار بودم و حقیقتا این وسط به سرم زده بود دانش سختافزاری خودم رو هم بالا ببرم. به همین خاطر ترم ۳ یا ۴ که بودم، قبل از این که به مدار منطقی برسم، خودخوان شروعش کردم. برام جالب بود و خب در عین حال ریاضیات گسسته هم برای من داشت مرور میشد. این مرور، در کنار دانش مدار منطقی من رو وادار کرد که کمی بیشتر بخوام در این حوزه ورود کنم. به همین خاطر، معماری کامپیوتر و ریزپردازنده رو هم حتی پیش از این که درسم بهشون برسه، مطالعه کردم.
وقتی به نتایج جالبی رسیدم، تصمیم گرفتم دوباره دانشم رو با مردم به اشتراک بذارم. به همین خاطر، این بار هم محتوا رو به زبون انگلیسی تولید کردم (لینک) و به رایگان در نسخه انگلیسی همین وبلاگ منتشرش کردم. خلاصه که اینجا تموم نمیشه. در اون سالها، بازار «اینترنت چیزها» یا IoT هم داغ بود و خب طبیعتا شروع کردم به یادگیری آردوینو، رزبریپای و … و پروژههای جالبی هم با اونها انجام دادم. البته خیلی از این پروژهها رو هنوز که هنوزه عمومی نکردم.
خلاصه این مورد هم گذشت و رسیدیم به شهریور ۹۶. یعنی جایی که من خیلی جدی و رسمی وارد بازار کار شدم.
ورود به بازار کار
در تیرماه ۹۶، در رویدادی شرکت کردیم که مرتبط با فعالان صنعت بازی رایانهای بود. این رویداد، به طور خاص به آهنگسازان و مهندسین صدا اختصاص داشت و خب بخاطر علاقه شخصیم به موسیقی، در این رویداد شرکت کردم. آخر رویداد گپ و گفتی با سخنران رویداد داشتم که باعث شد شخصی بیاد خودش رو معرفی کنه و بگه که تیمشون نیاز به آهنگساز داره. پس از مدتی، مدیر استودیو به من پیام داد و گفت بازیای در ژانر کودکه و خب نمیدونم چی شد که اون موقع، این بحث ادامه پیدا نکرد.
اما شهریور ۹۶ یکی از دوستانی که در همون استودیو مشغول بود، برای یک بازی دیگر من رو دعوت کرد به همکاری. یک مصاحبه ریزی داشتیم و پس از اون مصاحبه، قرار شد من برم و همکاری کنم. پس از این ماجرا، من رسما وارد اکوسیستم و بازار کار شدم تا به امروز.
سخن آخر
خب، در این مطلب هم مثل مطلب قبلی حجم خوبی از خاطرات من رو شاهد بودید. کل حرفی که میخواستم بزنم این بود که دوستان، از تجربه کردن و حتی شاخه شاخه پریدن؛ نترسید. این پرشها به خودی خود باعث میشن که شما در کارتون – حتی کارهای فریلنسری و پروژهای – به شدت موفقتر عمل کنید. یادتون باشه که زندگی، فانتر از اونیه که بخواید با زیادی جدی گرفتن؛ خرابش کنید.
مدت زیادیه که در نظر دارم مطلبی در مورد این که چطور برنامهنویس شدم رو قلمی کنم. مطالبی از این دست، نوشتنشون بسیار سختتر از چیزیه که فکرش رو هم بکنید. چرا که باید به گذشتههای دور سفر کنیم و خیلی از خاطرات گذشته رو هم مرور کنیم. بخصوص وقتی قراره در مورد چیزی مثل همین برنامهنویسی، بنویسیم. من قبلتر در همین وبلاگ، در مورد این رشته کامپیوتر چیه توضیح داده بودم (لینک). زمانی که اون پست رو نوشتم، فکر کنم دمدمای اعلام نتایج کنکور سراسری بود و طبیعتا خیلیها، دوست داشتن که با رشته تحصیلیشون آشنایی پیدا کنند. خلاصه، خواستم در این پست هم چیزی شبیه به همین موضوع بنویسم ولی با خودم گفتم بهتره که در مورد «داستان برنامهنویس شدن خودم» پست بنویسم.
من کی هستم؟
من محمدرضا حقیری هستم. احتمالا خیلیها من رو از «پروژه جبیر» بشناسن. اگر ماجرای پروژه جبیر رو نمیدونید، باید بگم که شاید یکی از اولین پروژههای جدی من بود که خیلی استارتاپگونه پیش میرفت. اطلاعات بیشتری از این پروژه رو میتونید از این لینک بخونید. اما الان چطور؟
فکر کنم پس از حدود ۱۰ سال حضور مداوم در جامعههای مختلفی مثل نرمافزار آزاد، جامعه فارسیزبان اوبونتو، جامعه Open Street Map (که البته در این آخری حضورم خیلی کمرنگتر بود) و جامعه بینایی ماشین (لینک) دیگه الان بدونید که شخص «محمدرضا حقیری» یک برنامهنویسه که دستی بر لینوکس، BSD، پایتون، کمی سختافزار داره و تبحر خاصی هم در تپه نوردی!
اگر دوست دارید بیشتر از من بدونید، در روزی که این پست نوشته شده (یعنی ۱۱ مهر ۱۴۰۰ هجری خورشیدی)، من چندین ماه از بیست و ششمین سال زندگیم میگذشته و در حال کار روی یکی از پروژههای خیلی جدی بودم و این پست رو برای این نوشتم که این داستان رو با شما به اشتراک بذارم. خب، من رو شناختید؟ بیایید بریم سراغ داستان برنامهنویس شدنم.
شروع برنامهنویسی
ما یک سری کتاب برنامهنویسی ویژوال بیسیک ۶ (لینک) در کتابخونه داشتیم. فکر کنم اواسط یا اواخر سال ۸۶ بود که من شروع کردم به خوندن یکی از این کتابا. برام خیلی جالب بود که چطور اینقدر این زبان هلوئه 🙂 از اون جالبتر این که اون زمان Windows Form هم چیزی بود که خیلی رو بورس بود و خیلی از برنامهنویسها ازش استفاده میکردند. یادمه که همون دوران، شرکت «پرند» هم یک مجموعه به اسم «کینگ» داشت (و البته فکر کنم هنوز هم داره) که درونش هزاران نرمافزار وجود داشت.
در یکی از دیسکهای کینگ، یک کتگوری Programming بود که ذیل اون، ویژوال استودیو قرار داشت. یادمه که با استفاده از دیسک مربوطه، ویژوال استودیو رو نصب کردم و شروع کردم به پیاده کردن چیزایی که در اون کتاب نوشته بود. یک فرم ساختم و یک لیبل زدم و روی لیبل نوشتم Hello World و شاید ندونید؛ ولی اون لحظه حسی که داشتم با حس آرمسترانگ وقتی رسیده بود روی ماه برابری میکرد. خلاصه که بعد از این که دورهای افتخار رو زدم، نشستم به خوندن باقی کتاب. اما میدونید چی شد؟ کتاب با VB6 آموزش میداد و فکر کنم من ویژوال استودیو ۲۰۰۵ و چنین چیزی رو داشتم.
خیلی دنبال فایل نصبی و حتی دیسک ویژوال بیسیک ۶ گشتم اما چیزی نیافتم. خلاصه در همون دوران بود که با انتشارات کلید آموزش (لینک) آشنا شدم. اولین کتابی که ازشون خوندم «کلید فتوشاپ» بود. در لیست کتابهاشون گشتم و دیدم که «کلید ویژوال بیسیک» هم دارند. اون کتاب رو خریدم و شروع کردم به خوندن و یادگیری از روی اون. خلاصه، بعد از چند ماه کشتی گرفتن، با ویژوال استودیو یک عدد ماشین حساب ساختم و دیگه شما میتونید حدس بزنید چقدر خوشحال بودم.
خلاصه که سال تحصیلی بعدیش، من تا حد خوبی روی مهارتهای توسعهدهندگیم کار کردم. البته خیلی از ابزارهایی مثل Multi Media Builder که استفاده میکردم، ابزار برنامهنویسی محسوب نمیشدند، اما خب بهرحال برای این که در جشنوارههای دانشآموزی و … شرکت کنم، بد نبودن. خلاصه که گذشت و گذشت و گذشت و رسیدیم به سال سوم راهنمایی. سوم راهنمایی من، سال جنجالی ۸۸ بود. سالی که تا حد زیادی افراد برای آینده خودشون، نگران شده بودند و طبیعتا من و خانواده من هم از این قاعده مستثناء نبودیم.
در این سال، یه جو قشنگی روی مدرسه حاکم شده بود. به طرز عجیبی مدرسه ما، دوست داشت که قطب تولید نرمافزار دانشآموزی باشه، قطب رباتیک منطقه خودش باشه و … . حقیقتا من این فرصت رو غنیمت شمردم و با همون ابزارهایی مثل Multi Media Builder نرمافزارهایی برای درسهای علوم و عربی ساختم. خیلی از فرمولها و روشهایی که در کلاس ریاضی یادمون میدادن رو با ویژوال بیسیک تبدیل به نرمافزار میکردم. در همین حین، به سبب تمرکز مدرسه روی مسابقات دانشآموزی رباتیک، سی++ هم تا حد خوبی یاد گرفته بودم. از طرفی انتشارات کلید هم «کلید دلفی» رو منتشر کرده بود و این یعنی که در حال یادگیری دلفی هم بودم.
شاید بگید چقدر هندونه؟ خب این همیشه روش من بوده. همیشه هم نتیجه داده و همیشه هم ازش راضیم 😁. شاید بد نباشه که اشاره کنم که همزمان با این ماجرا، به سبب داشتن وبلاگ روی بلاگفا هم کمی جاوااسکریپت (زمانی که جاوااسکریپت هنوز انقدر گسترده نبود) یاد گرفته بودم …
شروع پروژه جبیر
حالا دیگه دبیرستانی شده بودم و دانش خوبی در زمینه برنامهنویسی داشتم. اما خب یک مساله خیلی مهم پیش آمده بود، از تهران مهاجرت کرده بودیم بندرعباس (که به نظر من یکی از زیباترین و دوستداشتنیترین شهرهای کشورمونه) و در بندرعباس هنوز دوست پایهای نداشتم که با هم نرمافزار و ربات و اینا بسازیم. پس باید چی کار میکردم؟ حقیقتا سال اول دبیرستان رو مجددا مشغول توسعه مهارتها و دانشم شدم. اما پس از گذروندن سال اول، مدرسهم عوض شد و اونجا با دوست جدیدی آشنا شدم.
اما حالا صحبت دوست جدید بمونه برای بعد، در تابستانی که بین سال اول و دوم دبیرستان داشتم، یادمه یک شماره از «مجله دانشمند» رو خریدم که در اون، کتاب «طراحی و پیادهسازی سیستمهای عامل» از «اندرو تننباوم» رو معرفی کرده بود. نکته اینجا بود که انتهای اون مقاله، در مورد لینوس تروالدزِ، خلق لینوکس و دعواهای معروفش با اندرو تننباوم هم نوشته بود و من اینجا جرقهای در ذهنم زده شد. من باید سیستمعامل میساختم! پس از گذشت چند ماه و مهاجرت به لینوکس و تحقیق در موردش و همچنین غرق شدن در دنیای اپل و زندگی شخصی استیو جابز و … (شاید بشه گفت جوگیریهای رایج دوره نوجوانی) بالاخره به این نتیجه رسیدم که بهتره که پایه سیستمعامل من هم لینوکس باشه.
بعد از مدتی، به ذهنم رسید که به کامیونیتی اوبونتو مراجعه کنم و اونجا بپرسم. به همین خاطر این پست رو ایجاد کردم و یه سری سوال پرسیدم. احتمالا در همون تاپیک بتونید راهنماییهای دانیال بهزادی رو ببینید که خب بعدتر در پروژه مشابهی حتی با هم همکاری هم کردیم 😂
بگذریم، بهار ۹۱ یک نسخه کاستومشده اوبونتو به اسم «جبیر او اس» منتشر شد که از قضا یک پروژه جنجالی هم شد. اما اثرات جانبی جالبی هم داشت. شاید بتونم مهمترین اثرش رو «ورود رسمی به جامعه نرمافزار آزاد» بدونم، اثر دیگرش هم این بود که مدیر مدرسه ما گیر داد که الا و بلا شما باید بیای این رو ببری جشنواره خوارزمی 🙂 بردیمش جشنواره خوارزمی ولی اونجا مقبول نیفتاد. حالا ماجرای خوارزمی رو یک بار باید اساسیتر تعریف کنم که در مقوله این مقاله نمیگنجه.
خلاصه پروژه جبیر تا حدود ۹۴ ادامه داشت و بعدش به کل رفت به تاریخ پیوست. دلایل متعددی هم داشتم براش، اما خب فعلا تا همین جاش رو قبول کنید ازم.
و این داستان ادامه دارد …
اول که شروع کردم به نوشتن این داستان، فکر میکردم که میتونم در یک پست جمعش کنم، ولی دیدم که خیلی پیچیدهتر از این حرفاست و شاید ۳-۴ قسمت ازش دربیاد. اما خب در کل، قصدم اینه که تا زمانی که وارد بازار کار شدم رو برای شما تعریف کنم (یعنی دو پست نگهش دارم) و بعدا سر فرصت مناسبی، تجربیات کاری خودم هم باهاتون به اشتراک بذارم.
پس، فعلا این پست رو از من داشته باشید و منتظر قسمت بعدی باشید، قسمت بعدی احتمالا خیلی جذابتر خواهد بود 😁
مدتی میشه که در جامعه بینایی ماشین، دارم به صورت خیلی جدی در مورد بیناییماشین و ملزوماتش، تولید محتوا میکنم. از همین رو، تصمیم گرفتم که در قالب این پست وبلاگی، در مورد این که بینایی ماشین چیه و کجا کاربرد داره و چرا باید بلدش باشیم و از کجا باید شروع کنیم؛ بنویسم.
این مطلب، اصلا و ابدا قرار نیست «آموزش» باشه و همونطوری که ابتدای مطلب گفتم، صرفا «نقشه راه» برای شماست.
بینایی ماشین چیه؟
بینایی ماشین در واقع یکی از شاخههای علوم کامپیوتر محسوب میشه که هدفش، اینه که پردازش و درک تصاویر دیجیتال رو سادهتر کنه. بینایی ماشین در ترکیب با هوش مصنوعی، رباتیکز و سایر شاخههای مرتبط با علوم و یا مهندسی کامپیوتر، میتونه به بهبود زندگی افراد کمک شایستهای کنه.
شاخههای زیادی برای بینایی ماشین داریم اعم از تشخیص چهره، تشخیص متن، خواندن نویسههای نوری (OCR)، واقعیت افزوده، واقعیت مجازی و … . هرکدوم از این شاخهها، تخصصهای خاص خودش رو میطلبه که در ادامه مطالب بهش خواهیم پرداخت.
کجا کاربرد داره؟
کاربردهای بینایی ماشین، میتونه در بسیاری از جاها باشه. نمونهش مثلا همین پروژهای که من زده بودم:
همونطور که میبینید، این پروژه برای اندازهگیری اشیاء مختلف با کمک بینایی ماشین ساخته شده بود. همچنین، یک پروژه دیگر این بود که حروف اشاره (که مورد استفاده ناشنوایانه) رو تشخیص میداد. در دنیای امروز تقریبا در هر جایی که کوچکترین استفادهای از تصویر میشه، مثل ویرایش و ساخت تصویر؛ تشخیص اقلام درون تصویر و …؛ بینایی ماشین داره در ابعاد وسیعی استفاده میشه.
چرا باید بلدش باشیم؟
بایدی وجود نداره. یادگیریش به عنوان یک مهارت، کاملا میتونه شما رو به یک پروژه خفن، کار یا پول نزدیک کنه. حتی اگر قصد ندارید در این زمینه کار کنید هم میتونید با یادگیری بینایی ماشین به سادگی برای خودتون یک تفریح سالم بسازید.
از کجا شروع کنیم؟
خب مهمترین بخش این مطلب دقیقا همینجاست که قراره با هم یاد بگیریم که چه پیشنیازهایی برای یادگیری بینایی ماشین وجود داره. هر پیشنیاز رو با هم کمی بررسی خواهیم کرد 🙂
برنامهنویسی پایتون: از اونجایی که پایتون زبان سادهایه و اکثر آدمها دنبال یادگیریشن (و این یعنی منابع آموزشی خیلی خوبی براش هست) بهتره که پایتون رو تا حد خوبی یاد بگیرید. حد خوب، یعنی حدی که شما بتونید یک نرمافزار ساده ولی کاربردی رو باهاش توسعه بدید (مثلا یه ماشین حساب یا چیزی مشابه اون).
مقدمات یادگیری ماشین: بینایی ماشین به شکلی یکی از زیرمجموعههای هوش مصنوعی محسوب میشه. این نشون میده که اگر شما به الگوریتمها و تئوری یادگیری ماشین و … آشناییت کافی داشته باشید، میتونید در این فیلد هم پیشرفت قابل توجهی کنید. گذشته از این، یادگیری ماشین میتونه بهتون در «هوشمندسازی» بیشتر نرمافزارهای بینایی ماشین کمک کنه.
آشنایی مختصر با جاوا یا سی++: از اونجایی که پایتون یک زبان مفسری محسوب میشه، ممکنه خیلیجاها (مثلا در یک برد آردوینو) نتونیم مستقیم ازش استفاده کنیم و همچنین استفاده ازش پیچیدگی خاصی به همراه داشته باشه؛ بهتره یک زبان سطح پایینتر مثل سی++ هم کمی آشنا باشیم. همچنین اگر قصد این رو دارید که اپلیکیشن تلفن همراه بنویسید که از بینایی ماشین استفاده میکنه، بد نیست دستی هم در جاوا داشته باشید.
آشنایی با سختافزارها و سیستمهای نهفته (Embedded Systems): یکی از کاربردهای عظیم بینایی ماشین، فعالیتهای Surveillance میتونه باشه (البته این که این فعالیتها بد یا خوب هستند بحث جداییه). یکی از نمونههاش میتونه «سیستم حضور و غیاب با تشخیص چهره» باشه، یا حتی «دفترچه تلفن هوشمند» و … 🙂 به همین دلیل، بد نیست که کمی با سیستمهای نهفته و سختافزارهایی مثل Jetson Nano و Raspberry Pi آشنایی داشته باشید.
آشنایی با لینوکس: این واقعا نیاز به توضیح خاصی نداره، روایت داریم اگر لینوکس بلد نیستی، برنامهنویس نیستی 🙄
لیست بالا به شما کمک میکنه که محکمتر در زمینه بینایی ماشین، قدم بردارید. هرجاش رو که بلد نباشید میتونید با جستجو پیداش کنید و یاد بگیرید و از یادگیری، لذت ببرید 🙂
سخن آخر
از این که وقت گذاشتید و این مطلب رو خوندید ممنونم. در آینده، در قالب پستهای وبلاگ در مورد پروژههای بینایی ماشین و سایر پروژههای باحال، صحبت خواهم کرد. امیدوارم که این مطلب مفید فایده واقع شده باشه و وقتی که براش گذاشتید ارزشش رو داشته باشه.
وبلاگ شخصی محمدرضا حقیری، برنامهنویس، گیک و یک شخص خوشحال