بایگانی برچسب: s

نصب Phosh روی دبیان

گنوم، چندسال اخیر رو در حال بهبود تجربه کاربریش روی دستگاه‌هایی مثل گوشی‌های همراه و همچنین تبلت‌هاست. در کل، داره برای یک انقلاب در صفحات لمسی آماده میشه. حالا، یک رابط کاربری جالب به اسم 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 برای شما نصب خواهد شد. پس از نصب، کافیه که اول سرویسش رو فعال و سپس راه‌اندازی کنیم:

sudo systemctl enable phosh
sudo systemctl start phosh

سپس، صفحه قفل (که بالاتر عکسش رو قرار دادم) و بعد از اون، صفحه ورود رمز به شما نمایش داده میشه.

پس از ورود رمز، وارد صفحه منوی اصلی می‌شیم که از اونجا می‌تونیم به نرم‌افزارها و ابزارهای نصب شده روی سیستم دسترسی داشته باشیم:

خب، حالا با خیال راحت می‌تونیم از Phosh استفاده کنیم و لذت ببریم 😁

نکات مهم

از اونجایی که Phosh نرم‌افزار نوپا و نسبتا جدیدیه، لازمه چند نکته مهم رو در موردش متذکر بشم:

  • نسخه خاصی ازش در مخازن دبیان پایدار موجوده که خب برای یک تست دم دستی و ویرچوال‌باکسی، بهترین گزینه بود (حداقل برای من) و خب قاعدتا روی مخازن تستینگ و ناپایدار هم قرارش دادند. موقع نصب، مراقب باشید تا به ضررتون نشه 😁 ترجیحا نصب رو روی یک ماشین مجازی انجام بدید.
  • این میزکار خاص، برای صفحات لمسی خیلی بهینه شده و استفاده ازش با ماوس و کی‌برد تا حد زیادی سخته. اگر صفحه لمسی دارید که می‌تونید به سیستمتون وصلش کنید، احتمالا تجربه کاربری بهتری داشته باشید.
  • بعضی نرم‌افزارها اندازه‌شون برای من مشکل داشت (که احتمالا برمی‌گرده به ویرچوال باکس). اگر در جای دیگری امتحان بشه شاید اندازه صفحه و برنامه‌ها، مناسب باشه.

کدوم توزیع‌ها از Phosh پشتیبانی می‌کنند؟

این هم سوال مهمیه، تا جایی که دیدم PostmarketOS (که برمبنای آلپاین ساخته شده) و همچنین Mobian (که برپایه دبیانه) از این میزکار (یا بهتر بگم پوسته) پشتیبانی می‌کنند. در مورد سایر توزیع‌ها/سیستم‌عامل‌هایی که ممکنه گنوم رو اجرا کنند، ایده‌ای ندارم.

جمع‌بندی

این بلاگ اصلا قرار نبود نوشته شه، ولی امروز از سر خستگی (دقیقا خستگی 😂) جستجو کردم ببینم Phosh چطور می‌تونه روی دبیان دسکتاپ نصب بشه. امتحانش کردم و به نظرم پروژه تمیز، باحال و آینده‌داری اومد. حالا هم تستش کردم و هم یک سری ایده‌ اومد به ذهنم. در آینده، احتمالا بیشتر با Phosh کار کنم و در موردش بنویسم. در آخر هم بابت وقتی که صرف کردید و این مطلب رو خوندید، ازتون تشکر می‌کنم.

Share

ایده هایی برای پروژه های بینایی ماشین

چندی پیش، در مورد پیش‌نیازهای یادگیری بینایی ماشین در همین وبلاگ نوشته بودم (لینک) و بعد از اون هم در مطلبی در ویرگول، در مورد این که چرا موجودیتی به اسم «جامعه بینایی ماشین» رو راه انداختم (لینک) صحبت کردم. پس از انجام چندین پروژه و تولید چندین محتوا پیرامون این موضوع، امروز در این پست قراره که ایده هایی که شما می‌تونید در پروژه های بینایی ماشین و پردازش تصویر خودتون به کار بگیرید رو بررسی کنیم.

توجه داشته باشید که در این پست، فرض رو بر این گذاشتیم که شما با هوش مصنوعی، پایتون، بینایی ماشین و … آشنایی لازم و کافی رو دارید و حالا قصد دارید یک پروژه جدی باهاش انجام بدید اما نمی‌دونید باید چی کار کنید. اگر آشنایی ندارید هم مشکلی نیست، می‌تونید این مطلب رو صرفا برای ایجاد علاقه و یا رفع کنجکاوی بخونید 😁

ایده های مرتبط با تشخیص چهره

تشخیص چهره، همیشه یکی از پرطرفدارترین شاخه‌های پردازش تصویر و بینایی ماشین بوده است. چرا که با استفاده از تشخیص چهره، می‌توانیم عملیات جالبی انجام دهیم و پروسه‌های زیادی از یک کار بزرگتر را، خودکار کنیم. همچنین می‌توانیم امنیت خانه و محل کار و … را نیز با استفاده از تشخیص چهره تامین کنیم.

در لیست زیر، تعدادی از پروژه‌های مرتبط با تشخیص چهره رو برای شما فهرست کرده‌ام:

  • حضور و غیاب مبتنی بر چهره
  • دوربین امنیتی (به این شکل که وقتی شخص ناشناسی وارد حریم دوربین شد از طریق ایمیل یا SMS و … به شما اطلاع بده)
  • قفل هوشمند ( به شکلی که اگر شما رو دید در رو باز کنه و در غیر این صورت، یک سیستم مانند دزدگیر یا سیستم امنیت خونه رو راه‌اندازی کنه)
  • تشخیص حالت و احساسات چهره
  • تشخیص خواب‌آلودگی (مثلا در یک کلاس این پروژه می‌تونه کاربردی باشه).

همه ایده‌های بالا، به سادگی قابل انجام هستند. فقط کافیه که کار با کتابخانه‌ها و تئوری پردازش تصویر رو بلد باشید. شاید دو سه روزه بتونید یکی از این پروژه‌ها رو به ثمر برسونید 😁

ایده‌ های مرتبط با تشخیص کرکتر

نتایج آزمایش روی دیتاست آزمایشی

تشخیص نوری نویسه یا Optical Character Recognition که به اختصار به اون OCR هم گفته می‌شه، یکی از شاخه‌های پرطرفدار دیگر در حوزه بینایی ماشین می‌تونه به حساب بیاد. پروژه‌هایی که در این حوزه انجام می‌شن به شدت کاربردی هستند و طبیعیه که در حوزه‌های مختلفی کاربرد خواهند داشت. در اینجا تعدادی از ایده‌هایی که می‌تونید روش کار کنید رو اینجا فهرست کردم:

  • تشخیص و استخراج شماره پلاک (که پیش‌تر در موردش نوشتم – لینک)
  • تشخیص و حل مسائل ریاضی/فیزیک (که این هم پیش‌تر در مورد نوشتم – لینک)
  • تشخیص دست‌خط فارسی
  • تشخیص خط نستعلیق (و در کل خوشنویسی) فارسی
  • تشخیص نسخه پزشکی (نکته جالب اینه که در نسخ پزشکی، بسیاری از خط‌خطی‌هایی که می‌بینید در واقع روش مصرف و دوزاژ دارو هستند، که طبق کدگذاری خاصی نوشته می‌شن).

البته باید این نکته رو هم عرض کنم خدمتتون که دنیای OCR خیلی گسترده‌ست. تقریبا هرجایی که شما با نوشتن سر و کار داشته باشید، می‌تونید از OCR هم اونجا استفاده کنید. خیلی چیزا اینجا به خلاقیت و نیازهای خودتون برمی‌گرده. اگر ایده‌ دیگری داشتید، می‌تونید در بخش نظرات همین مطلب با من به اشتراک بذارید.

ایده های مرتبط با پزشکی

هوش مصنوعی در علم پزشکی، جایگاه خاصی در سال‌های اخیر داشته. چرا که همه دانشمندان کامپیوتر و همچنین پزشکی، دریافتند که با استفاده از راه‌حل‌های هوشمند، می‌تونند به حد قابل توجهی، خطاهای پزشکی رو کاهش بدند. همچنین تحقیقات دارو و واکسن هم به شدت سریع‌تر می‌تونن انجام بدند. برای مثال، همین دنیاگیری ویروس کرونا که در سال ۲۰۱۹ آغاز شد و کماکان ادامه داره رو بررسی کنیم، بارها از این که از هوش مصنوعی برای پیدا کردن ترکیبات دارویی موثر بر ویروس استفاده شده، صحبت کردند. همچنین در پروسه ساخت واکسن هم بسیاری از مراحل رو به ماشین سپردند و به هوش ماشینی اعتماد کردند. شاید یکی از دلایلی که واکسن این بیماری انقدر سریع ساخته شد، استفاده از همین راهکارهای هوشمند در تولید بوده.

بینایی ماشین هم استثناء نیست و طبیعتا می‌تونه خیلی به کمک افراد بیاد. در این بخش، تعداد زیادی از ایده‌هایی که می‌تونه به پزشک‌ها در شناخت بهتر مشکلات بیمارهاشون کمک کنه رو فهرست کردم و خب بد نیست اگر شما هم سراغش برید و سعی کنید یکیش رو پیاده کنید (این بخش می‌تونه برای دانشجویان مهندسی پزشکی و پزشکی؛ بسیار مفید باشه)

  • تشخیص نوع تومور مغزی (تصویر این بخش، پروژه‌ای که خودم انجام دادم)
  • تشخیص رتینوپاتی دیابتی در اشخاص مبتلا به دیابت
  • تشخیص MS و مراحل مختلف اون بر اساس MRI
  • تشخیص سلول‌های سرطانی
  • تشخیص میزان درگیری ریه در بیماری‌های تنفسی (مانند COVID-19)
  • تشخیص ناهنجاری‌های پوستی
  • تشخیص آسیب‌های استخوان
  • تشخیص آسیب‌دیدگی‌ها و پوسیدگی‌های دندان

طبیعتا این‌ها، همه کارهایی که می‌تونیم در حوزه پزشکی با کمک بینایی ماشین و پردازش تصویر انجام بدیم نیستن و این دامنه می‌تونه به شدت گسترده‌تر باشه. طبیعیه که گستردگی این دامنه به خلاقیت خودتون و نیازهاتون برمی‌گرده. همچنین طبیعتا اگر شما دانشجوی مهندسی پزشکی یا رشته پزشکی و رشته‌های مرتبط باشید، احتمالا ایده‌های بهتری خواهید داشت.

سایر حوزه‌ها

چندین و چند حوزه دیگر هست که خب مثل باقی حوزه‌های پوشش داده شده در این مطلب، نمیشه ایده‌های پروژه‌های بینایی ماشین و پردازش تصویرشون رو فهرست کرد. به همین خاطر، توضیح اجمالی راجع به هر کدوم می‌دم تا شما ببینید که کدوم حوزه رو بیشتر دوست خواهید داشت و در کدوم حوزه ممکنه بتونید ایده‌پردازی بهتری داشته باشید.

تشخیص حرکت یا Action Detection

این حوزه به طور خاص، می‌تونه برای کارهایی مثل تشخیص و ترجمه همزمان زبان اشاره (لینک)، تشخیص حرکات ورزشی و یا تشخیص «نیت» افراد بشه. برای مثال، می‌تونیم سیستمی بسازیم که حرکات بعدی فرد در یک نبرد تن به تن (مثل مسابقه بوکس) رو پیش‌بینی کنه و به مربی‌ها و نوآموزهای اون رشته اطلاع بده.

خودروهای خودران

خودروهای خودران یا Self-Driving که پیش‌تر هم ازشون در همین وبلاگ صحبت کرده بودم (لینک) می‌تونن با استفاده از بینایی ماشین و پردازش تصویر، تابلوهای راهنمایی، رفتار سایر رانندگان، موانع در مسیر و … رو تشخیص بدند. این حوزه البته پیچیدگی زیادی داره اما کار کردن روی بخش‌های مختلفش می‌تونه برای یادگیری جوانب مختلف ماجرا جذاب و جالب و مفید باشه.

مصرف انرژی

حوزه انرژی هم حوزه جالبی می‌تونه برای پروژه‌های بینایی ماشین باشه. برای مثال OCR ای که بتونه دیتای کنتور گاز/برق رو به متن تبدیل کنه و اون رو با یک مرکز محاسبه قیمت، چک کنه و قیمت رو به ما اعلام کنه. همچنین می‌شه عکس‌های حرارتی از خانه‌ها و … تهیه کرد و با استفاده از بینایی ماشین دقیقا بررسی کرد که کجاها انرژی بیشتری داره از دست میره و … .

این پروژه‌ها به خودی خود شاید جالب به نظر نرسن اما ترکیبشون با IoT و هوشمندسازی در سطوح دیگر، طبیعتا می‌تونه جذاب و حتی پول‌ساز هم باشه.

کشاورزی

این هم گفتن نداره، شما کافیه که یک سری عکس هوایی از زمین‌های کشاورزی داشته باشید. احتمالا خیلی راحت بتونید سیستمی توسعه بدید که آفات رو شناسایی کنه. همینطور می‌تونید نوع خاک و … هم از روی این عکس‌ها طبقه‌بندی کنید و پیشنهاد بدید که چه محصولی در این زمین کشت بشه بهتره. در حوزه مصرف انرژی هم می‌تونید یکی از پروژه‌ها رو بردارید بیارید اینجا و ازش بهره‌برداری کنید. چی از این بهتر؟

ضمن این که امنیت زمین کشاورزی و گلخانه، بررسی نور و رنگ و … هم می‌تونن اینجا کاربردی باشند.

جمع‌بندی مطلب

در این مطلب، ایده‌هایی که می‌تونید بعنوان یک پروژه تفریحی یا جدی پیاده‌سازی کنید رو بررسی کردیم. همچنین این ایده‌ها، به جز این که می‌تونن رزومه خوبی برای شما بسازند طبیعتا می‌تونن پایه یک کسب و کار و یا یک استارتاپ باشند که شانس خوبی برای به پول رسیدن داره. به همین خاطر هم ممنون میشم اگر هر کدوم از این ایده‌ها رو پیاده‌سازی کردید در بخش کامنت همین مطلب در موردش بنویسید و به من اطلاع بدید تا ببینم چه کردید.
همچنین لازم به ذکره که اگر دوست دارید مطالب فنی/علمی دیگری از من بخونید، می‌تونید به ویرگول من هم مراجعه کنید. در پایان هم بابت وقتی که گذاشتید، ازتون تشکر می‌کنم و امیدوارم در آینده باز هم بتونم در این وبلاگ، مطلب بنویسم.

 

Share

خواندن پلاک خودرو با کمک YOLOv5 و پایتون

مدت‌ها پیش، من شروع به نوشتن پیرامون بینایی ماشین و پردازش تصویر کردم (برای مثال، یکی از نتایجی که از این موضوع گرفتم راه‌اندازی جامعه بینایی ماشین بود) و کم کم تلاشم بر این شد که هوش مصنوعی و یادگیری عمیق و یادگیری ماشین و … هم وارد ماجرا کنم چرا که دونستن 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 منتشر شده و بازنشر و استفاده از محتویاتش کاملا آزاده. فقط توجه لازم داشته باشید که دیتاستی که برای آموزش استفاده شده آزاد نیست و این آزادی در استفاده شامل بخش‌هایی از این مطلب میشه که مسولیتش با منه (به طور کلی هرچی که شما در این پست خوندید)

سخن آخر

این پست برخلاف پست‌های دیگر این وبلاگ به شدت طولانی شد و از بابت این که وقت زیادی برای خوندنش گذاشتید، واقعا از شما متشکرم. در پایان جا داره از شما دعوت کنم که به ویرگول من هم سر بزنید تا اونجا موارد فنی و تجربیات دیگر من رو بخونید. همچنین، اگر این مطلب برای شما مفید بود کافیه که روی تصویر زیر کلیک کنید و من رو به یک فنجان قهوه به انتخاب خودتون مهمان کنید 🙂

Share

با هوش مصنوعی، ریاضی ۱ رو پاس کن!

دقیقا دو هفته پیش، در نسخه انگلیسی وبلاگ در مورد 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 و از همه مهم‌تر درگیر شدن با چند مساله و به قولی، دردهای دنیای واقعی. از نتیجه کاملا راضی بودم و هستم، اما فکر نکنم در آینده این پروژه خیلی برام راضی‌کننده باشه.

احتمالا بعد از مدتی به این پروژه برگردم و بزرگترین مشکلش – یعنی شباهت زیاد ورودی‌ها به هم – رو طور دیگری هندل کنم. برای این که ببینیم یه چیزی در پوزیشن توان یه چیز دیگه قرار گرفته یه چاره‌ای بیاندیشم و … . خلاصه که راه برای بهبودش زیاده و این بهبود‌ها رو شخصا پیگیر هستم که در این پروژه اعمال کنم. شاید هم لازم باشه داده ورودی رو افزایش داد یا حتی مدل مورد استفاده رو عوض کرد.

در نهایت، از شما بابت وقتی که برای خوندن این مطلب گذاشتید، ممنونم. امیدوارم که این مطلب مفید واقع شده باشه و به دردتون خورده باشه. ضمن این که اگر به این تیپ مسائل و مطالب علاقمند هستید، می‌تونید من رو در ویرگول هم دنبال کنید و اونجا هم مطالبم رو بخونید. اگرچه در ویرگول عمده مطالبم مرتبط با بیزنس، موفقیت و ایناست.

در نهایت از شما خواهش می‌کنم که اگر این مطلب براتون مفید بود، یک قهوه به انتخاب خودتون مهمانم کنید تا موقع نوشیدن قهوه به یادتون باشم و از این دست مطالب، بیشتر تولید کنم.

Share

داستان برنامه‌نویس شدن من – قسمت دوم

در پست پیشین، یعنی قسمت اول داستان برنامه‌نویس شدنم (لینک) از زمانی که شروع به خوندن کتاب‌های ویژوال بیسیک کردم تا زمانی که پروژه جبیر رو راه انداختم رو به تفصیل توضیح دادم. فکر می‌کنم داستان برنامه‌نویس شدن من، داستان جالبی برای خیلی از دوستانی که وبلاگم رو میخونن بوده و به همین دلیل، تصمیم گرفتم که قسمت دومش هم حتما بنویسم.

همونطوری که در قسمت قبلی قولش رو داده بودم، قراره که در این قسمت از بعد از پروژه جبیر تا زمانی که وارد بازار کار شدم رو توضیح بدم و بگم چی شد که اینطوری شد. در مورد مسیرهای شغلی قبل‌تر توضیح دادم (مثلا در پست چگونه توزیع لینوکس بسازیم و یا پست چگونه بازی‌ساز شویم) همینطور حتی ابزارها و وسایلی که در مسیر شغل‌های مختلف طراحی و تولید کردم (مثل صداگذاری روی بازی کامپیوتری) هم در این وبلاگ پیش‌تر توضیح دادم. فلذا در این مطلب، اصلا و ابدا به مسیرهای شغلی اشاره نخواهم کرد.

ورود به دانشگاه

در طی این سالها، یعنی از حدود ۹۱ تا ۹۳ راه‌های زیادی رو رفتم که سرویس‌ها و نرم‌افزارهای خاصی رو طراحی کنم و خب دروغ چرا، تا حد زیادی هم رویای استیو جابز یا زاکربرگ شدن هم در سر داشتم و خب کارهای مختلفی مثل ایجاد انجمن‌های اینترنتی مختلف (ایران‌بی‌اس‌دی، ایران‌هکینتاش و …) گرفته تا برپا کردن شبکه‌های اجتماعی و نرم‌افزارهای آنلاین دیگر (اکسوال، نکست‌کلود و …) رو انجام می‌دادم. راستش این راه‌ها من رو به قول خارجی‌ها Satisfy نمی‌کرد و همچنان دنبال این بودم که یک سیستم عامل خوب بسازم!

خلاصه شد سال ۹۲ و ما از شهر بندرعباس به تهران برگشتیم. اون سال، سال پیش‌دانشگاهی من بود (و بد نیست این داستانکم رو هم پیرامونش بخونید) و اون سال، یک تصمیم بزرگ هم گرفتم. تصمیمم این شد که جبیر به جای این که مبتنی بر اوبونتو (یک توزیع از گنو/لینوکس)، یک نسخه شخصی‌سازی‌شده از FreeBSD باشه. از همین رو، شروع کردم به رفتن به IRC های مختلف، سوال پرسیدن و مستندات خوندن. بعد از چندین ماه مطالعه، وضعیت اینترنت خونه و خودم تا حد خوبی پایدار شد و بعد شروع کردم به انجام تغییرات روی کد FreeBSD.

بعد از مدتی، پروژه جبیر تا حد خوبی پیش رفت و گذشت و گذشت و من کنکور دادم (داستانی از کنکور هم اینجا نوشتم) و وقتی نتایج اومد، فهمیدم که در دانشگاه آزاد اسلامی واحد تهران مرکز در رشته مهندسی کامپیوتر و گرایش سخت‌افزار قبول شدم.

داستان برنامه‌نویس شدن من - محمدرضا حقیریشرکت در لاگ‌ها و رویدادها و آخر و عاقبت پروژه جبیر

حضور در تهران و دانشجو شدن، به من کمک کرد که وارد جامعه بشم و در رویدادهای نرم‌افزار آزاد و متن‌باز و سایر رویدادها (مثل PyCon و …) شرکت کنم. اولین رویدادی که شرکت کردم، رویدادی بود به اسم «جامعه رایانش ابری آزاد». در اون رویداد با KVM و Docker آشنا شدم و تا حد زیادی هم دانشم در زمینه Containerها و مجازی‌سازی تا حد خوبی بالا رفت.

در حاشیه شرکت در این رویدادها، بسیاری از افرادی که از انجمن اوبونتو و یا تکنوتاکس یا لینوکس‌ری‌ویو می‌شناختم رو حضوری دیدم و باهاشون آشنا شدم و حتی رفاقت‌هایی شکل گرفت. پس از مدتی، در بحثی دوستانه، تصمیم بر آن شد که پروژه جبیر کلا منحل بشه و پروژه‌ای به این بزرگی که نیازمند دانش فنی بالا، پول زیاد و همچنین حوصله فراوونه، به زمانی موکول شه که بتونم از پس حداقل یک موردش بربیام. فلذا پروژه جبیر اعلام شد که دیگه قرار نیست ادامه پیدا کنه.

اگر دوست دارید ببینید که پروژه جبیر چه شکلی بوده، می‌تونید این لینک مربوط به وب آرکایو رو هم ببینید: لینک. در ادامه، بنا به دلایلی (که در ادامه این مطلب بهش می‌پردازیم) تصمیم شد که پروژه جبیر بیشتر روی فاز سخت‌افزاری باشه و چند مطلب هم در موردش حتی نوشتم(لینک).

داستان برنامه‌نویس شدن من - محمدرضا حقیری

یادگیری روبی، ورود به حوزه سخت‌افزار و دیگر هیچ!

مهرماه ۹۳ بود که من خیلی جدی تصمیم گرفتم حداقل یک زبان برای توسعه وب رو جدی یاد بگیرم. قبل‌ترش، کتاب «از این پس پایتون» رو خونده بودم و به همین خاطر هم کمی با پایتون و فلسک آشنا بودم. دوستی یک کتاب جنگو هم برای من ارسال کرد. اما در همون هنگام در بحثی در IRC که دقیق یادم نیست مربوط به occc بود یا لاگ کرج، دوستی به من پیشنهاد کرد که روبی و روبی‌آن‌ریلز رو یاد بگیرم. در ادامه‌ش، توصیه کرد که حتما با دیتابیس‌ها آشنا شم و کمی هم مهندسی نرم‌افزار یاد بگیرم.

من هم این توصیه رو عملی کردم و شروع کردم به خوندن روبی. شاید باورتون نشه ولی از اونجایی که دیدم زبون روبی، خیلی در ایران زبون روتینی نیست و خیلی‌ها باهاش غریبه‌ند، تصمیم گرفتم دانش خودم رو در قالب یک کتاب الکترونیکی دربیارم و خب نتیجه پس از مدت نسبتا طولانی شد کتاب آموزش روبی که به رایگان قابل دانلوده.

خب همونطوری که ابتدای متن گفتم، من گرایش سخت‌افزار بودم و حقیقتا این وسط به سرم زده بود دانش سخت‌افزاری خودم رو هم بالا ببرم. به همین خاطر ترم ۳ یا ۴ که بودم، قبل از این که به مدار منطقی برسم، خودخوان شروعش کردم. برام جالب بود و خب در عین حال ریاضیات گسسته هم برای من داشت مرور می‌شد. این مرور، در کنار دانش مدار منطقی من رو وادار کرد که کمی بیشتر بخوام در این حوزه ورود کنم. به همین خاطر، معماری کامپیوتر و ریزپردازنده رو هم حتی پیش از این که درسم بهشون برسه، مطالعه کردم.

وقتی به نتایج جالبی رسیدم، تصمیم گرفتم دوباره دانشم رو با مردم به اشتراک بذارم. به همین خاطر، این بار هم محتوا رو به زبون انگلیسی تولید کردم (لینک) و به رایگان در نسخه انگلیسی همین وبلاگ منتشرش کردم. خلاصه که اینجا تموم نمیشه. در اون سالها، بازار «اینترنت چیزها» یا IoT هم داغ بود و خب طبیعتا شروع کردم به یادگیری آردوینو، رزبری‌پای و … و پروژه‌های جالبی هم با اونها انجام دادم. البته خیلی از این پروژه‌ها رو هنوز که هنوزه عمومی نکردم.

خلاصه این مورد هم گذشت و رسیدیم به شهریور ۹۶. یعنی جایی که من خیلی جدی و رسمی وارد بازار کار شدم.

داستان برنامه‌نویس شدن من - محمدرضا حقیری

ورود به بازار کار

در تیرماه ۹۶، در رویدادی شرکت کردیم که مرتبط با فعالان صنعت بازی رایانه‌ای بود. این رویداد، به طور خاص به آهنگسازان و مهندسین صدا اختصاص داشت و خب بخاطر علاقه شخصیم به موسیقی، در این رویداد شرکت کردم. آخر رویداد گپ و گفتی با سخنران رویداد داشتم که باعث شد شخصی بیاد خودش رو معرفی کنه و بگه که تیمشون نیاز به آهنگساز داره. پس از مدتی، مدیر استودیو به من پیام داد و گفت بازی‌ای در ژانر کودکه و خب نمی‌دونم چی شد که اون موقع، این بحث ادامه پیدا نکرد.

اما شهریور ۹۶ یکی از دوستانی که در همون استودیو مشغول بود، برای یک بازی دیگر من رو دعوت کرد به همکاری. یک مصاحبه ریزی داشتیم و پس از اون مصاحبه، قرار شد من برم و همکاری کنم. پس از این ماجرا، من رسما وارد اکوسیستم و بازار کار شدم تا به امروز.

سخن آخر

خب، در این مطلب هم مثل مطلب قبلی حجم خوبی از خاطرات من رو شاهد بودید. کل حرفی که می‌خواستم بزنم این بود که دوستان، از تجربه کردن و حتی شاخه شاخه پریدن؛ نترسید. این پرش‌ها به خودی خود باعث میشن که شما در کارتون – حتی کارهای فریلنسری و پروژه‌ای – به شدت موفق‌تر عمل کنید. یادتون باشه که زندگی، فان‌تر از اونیه که بخواید با زیادی جدی گرفتن؛ خرابش کنید.

موفق باشید 🙂

 

Share

نقشه راه بینایی ماشین برای مبتدیان

مدتی میشه که در جامعه بینایی ماشین، دارم به صورت خیلی جدی در مورد بینایی‌ماشین و ملزوماتش، تولید محتوا می‌کنم. از همین رو، تصمیم گرفتم که در قالب این پست وبلاگی، در مورد این که بینایی ماشین چیه و کجا کاربرد داره و چرا باید بلدش باشیم و از کجا باید شروع کنیم؛ بنویسم.

این مطلب، اصلا و ابدا قرار نیست «آموزش» باشه و همونطوری که ابتدای مطلب گفتم، صرفا «نقشه راه» برای شماست.

بینایی ماشین، بینایی کامپیوتری

بینایی ماشین چیه؟

بینایی ماشین در واقع یکی از شاخه‌های علوم کامپیوتر محسوب میشه که هدفش، اینه که پردازش و درک تصاویر دیجیتال رو ساده‌تر کنه. بینایی ماشین در ترکیب با هوش مصنوعی، رباتیکز و سایر شاخه‌های مرتبط با علوم و یا مهندسی کامپیوتر، می‌تونه به بهبود زندگی افراد کمک شایسته‌ای کنه.

شاخه‌های زیادی برای بینایی ماشین داریم اعم از تشخیص چهره، تشخیص متن، خواندن نویسه‌های نوری (OCR)، واقعیت افزوده، واقعیت مجازی و … . هرکدوم از این شاخه‌ها، تخصص‌های خاص خودش رو می‌طلبه که در ادامه مطالب بهش خواهیم پرداخت.

کجا کاربرد داره؟

کاربردهای بینایی ماشین، می‌تونه در بسیاری از جاها باشه. نمونه‌ش مثلا همین پروژه‌ای که من زده بودم:

اندازه‌گیری اشیا با بینایی ماشین

همونطور که می‌بینید، این پروژه برای اندازه‌گیری اشیاء مختلف با کمک بینایی ماشین ساخته شده بود. همچنین، یک پروژه دیگر این بود که حروف اشاره (که مورد استفاده ناشنوایانه) رو تشخیص میداد. در دنیای امروز تقریبا در هر جایی که کوچکترین استفاده‌ای از تصویر میشه، مثل ویرایش و ساخت تصویر؛ تشخیص اقلام درون تصویر و …؛ بینایی ماشین داره در ابعاد وسیعی استفاده میشه.

چرا باید بلدش باشیم؟

بایدی وجود نداره. یادگیریش به عنوان یک مهارت، کاملا میتونه شما رو به یک پروژه خفن، کار یا پول نزدیک کنه. حتی اگر قصد ندارید در این زمینه کار کنید هم می‌تونید با یادگیری بینایی ماشین به سادگی برای خودتون یک تفریح سالم بسازید.

از کجا شروع کنیم؟

خب مهم‌ترین بخش این مطلب دقیقا همینجاست که قراره با هم یاد بگیریم که چه پیش‌نیازهایی برای یادگیری بینایی ماشین وجود داره. هر پیش‌نیاز رو با هم کمی بررسی خواهیم کرد 🙂

  • برنامه‌نویسی پایتون: از اونجایی که پایتون زبان ساده‌ایه و اکثر آدمها دنبال یادگیریشن (و این یعنی منابع آموزشی خیلی خوبی براش هست) بهتره که پایتون رو تا حد خوبی یاد بگیرید. حد خوب، یعنی حدی که شما بتونید یک نرم‌افزار ساده ولی کاربردی رو باهاش توسعه بدید (مثلا یه ماشین حساب یا چیزی مشابه اون).
  • مقدمات یادگیری ماشین: بینایی ماشین به شکلی یکی از زیرمجموعه‌های هوش مصنوعی محسوب میشه. این نشون میده که اگر شما به الگوریتم‌ها و تئوری یادگیری ماشین و … آشناییت کافی داشته باشید، می‌تونید در این فیلد هم پیشرفت قابل توجهی کنید. گذشته از این، یادگیری ماشین می‌تونه بهتون در «هوشمندسازی» بیشتر نرم‌افزارهای بینایی ماشین کمک کنه.
  • آشنایی مختصر با جاوا یا سی++: از اونجایی که پایتون یک زبان مفسری محسوب میشه، ممکنه خیلی‌جاها (مثلا در یک برد آردوینو) نتونیم مستقیم ازش استفاده کنیم و همچنین استفاده ازش پیچیدگی خاصی به همراه داشته باشه؛ بهتره یک زبان سطح پایین‌تر مثل سی++ هم کمی آشنا باشیم. همچنین اگر قصد این رو دارید که اپلیکیشن تلفن همراه بنویسید که از بینایی ماشین استفاده می‌کنه، بد نیست دستی هم در جاوا داشته باشید.
  • آشنایی با سخت‌افزارها و سیستم‌های نهفته (Embedded Systems): یکی از کاربردهای عظیم بینایی ماشین، فعالیت‌های Surveillance می‌تونه باشه (البته این که این فعالیت‌ها بد یا خوب هستند بحث جداییه). یکی از نمونه‌هاش می‌تونه «سیستم حضور و غیاب با تشخیص چهره» باشه، یا حتی «دفترچه تلفن هوشمند» و … 🙂 به همین دلیل، بد نیست که کمی با سیستم‌های نهفته و سخت‌افزارهایی مثل Jetson Nano و Raspberry Pi آشنایی داشته باشید.
  • آشنایی با لینوکس: این واقعا نیاز به توضیح خاصی نداره، روایت داریم اگر لینوکس بلد نیستی، برنامه‌نویس نیستی 🙄

لیست بالا به شما کمک می‌کنه که محکم‌تر در زمینه بینایی ماشین، قدم بردارید. هرجاش رو که بلد نباشید می‌تونید با جستجو پیداش کنید و یاد بگیرید و از یادگیری، لذت ببرید 🙂

سخن آخر

از این که وقت گذاشتید و این مطلب رو خوندید ممنونم. در آینده، در قالب پست‌های وبلاگ در مورد پروژه‌های بینایی ماشین و سایر پروژه‌های باحال، صحبت خواهم کرد. امیدوارم که این مطلب مفید فایده واقع شده باشه و وقتی که براش گذاشتید ارزشش رو داشته باشه.

Share

از کجا برای پروژه‌های هوش‌مصنوعی و علوم داده، داده مناسب تهیه کنیم؟

خیلی از افرادی که این روزها، میخوان پروژه‌هایی در حوزه‌های مختلف هوش مصنوعی مثل یادگیری ماشین، یادگیری عمیق، علوم داده و … انجام بدن یک گلوگاه بسیار بزرگ دارند و اون «داده» است. خیلی‌ها واقعا نمی‌دونن از کجا می‌تونن داده‌های مناسب پروژه‌هاشون به دست بیارن. در این مطلب، قراره که این موضوع رو پوشش بدم.

منابع مناسب داده برای پروژه‌های شما

در این بخش، با هم چندین منبع مناسب برای پیدا کردن داده رو بررسی خواهیم کرد. فقط قبل از هرچیز این رو بگم که این منابع می‌تونن تغییر کنن در طول زمان پس هرچه که در این مطلب بیان شده رو در مرداد ۱۴۰۰ معتبر بدونید و اگر مدتی بعد از انتشار این مطلب دارید مطالعه‌ش می‌کنید، با جست‌وجو و پرس‌وجو در مورد این منابع، اطلاعات به‌روزتر دریافت کنید.

Kaggle

وبسایت کگل، یک محیط تقریبا مشابه شبکه‌های اجتماعی برای دانشمندان داده و متخصصین هوش مصنوعی به حساب میاد. در این وبسایت شما می‌تونید مجموعه داده (Dataset) های خوبی رو پیدا کنید. همچنین، می‌تونید کارهایی که ملت روی اون داده‌ها انجام دادن رو در قالب Kaggle Kernel (به نوعی همون جوپیتر نوت‌بوک خودمون) ببینید و یا کارهای خودتون هم به اشتراک بذارید.

برای دسترسی به کگل، می‌تونید روی این لینک کلیک کنید.

Academic Torrents

این وبسایت هم وبسایت جالبیه (و به نوعی مرتبط با بخش بعدی). در واقع هر حرکت آکادمیکی که زده شده و اطلاعاتش هم همزمان منتشر کردند رو در خودش داره. چرا؟ چون جست و جو در محتوای آکادمیک نسبتا سخته و این وبسایت اون کار رو براتون راحت کرده. همچنین یک بخش خوبی برای مجموعه‌داده (لینک) هم در این وبسایت در نظر گرفته شده.

برای دسترسی به این وبسایت، می‌تونید از طریق این لینک اقدام کنید.

وبسایت دانشگاه‌ها

همونطوری که در بخش قبلی گفتم، بسیاری از دانشگاه‌ها (و در کل، فضاهای آکادمیک) تحقیقات زیادی انجام میدن و داده‌های اون تحقیقات رو هم معمولا منتشر می‌کنن. چرا که یکی از اصول مطالعات آماری، اینه که داده‌ها به صورت شفاف منتشر بشن (شاید دلیلش اینه که بعدها، یکی بخواد خودش اون آزمایش و مطالعه رو تکرار کنه و …).

به همین خاطر، وبسایت دانشگاه‌ها – چه ایرانی و چه خارجی – می‌تونه محل خوبی باشه برای مراجعه و پیدا کردن داده‌های خوب برای مطالعه.

دیتاست‌های متن‌باز شرکت‌ها

بسیاری از شرکت‌های بزرگ مثل گوگل، فیسبوک، آمازون و …، میان و حجم خوبی از داده‌هایی که قبل‌تر در تحقیقاتشون استفاده کردند رو به صورت اوپن‌سورس، منتشر می‌کنن. پیدا کردن این دیتاست‌ها هم اصلا کار سختی نیست.

برای مثال، در این لینک می‌تونید دیتاست‌های گوگل رو ببینید. یکی از نمونه‌هایی که خود گوگل اینجا مطرح کرده، دیتاست مرتبط با بیماری کووید-۱۹ است. (لینک)

چرا این شرکت‌ها، دیتاست‌ها رو منتشر می‌کنن؟ باز هم میگم دقیقا به همون دلیلی که دانشگاه‌ها منتشر می‌کنن. شاید افراد یا سازمان‌هایی باشن که بخوان تحقیقات و مطالعات رو برای خودشون تکرار کنند و یا نتیجه آزمایشات و … رو صحت‌سنجی کنند.

خزیدن (Crawling) صفحات وب

خب، بعضی وقتا هم داده‌ای که ما نیاز داریم، توسط شرکت‌ها یا دانشگاه‌ها منتشر نشده. پس در این حالت چه کار می‌کنیم؟ اگر داده مورد نظر، در اینترنت موجود باشه، می‌تونیم یک خزنده (Crawler) بسازیم و با اون کارمون رو پیش ببریم.

در بسیاری از زبان‌های برنامه‌نویسی و چارچوب‌هاشون، ابزارهای بسیار خوبی برای کراول کردن صفحات وب وجود داره. یکی از بهترین نمونه‌هاش میتونه BeautifulSoup در پایتون باشه. در مطالب بعدی، احتمالا با استفاده از این ابزار، یک خزنده برای وبسایت‌های مختلف خواهیم نوشت.

دوربین، میکروفن، حرکت!

اگر داده‌های مورد نیاز ما حتی به شکلی که بتونیم کراول کنیم موجود نبود چی؟ ساده‌ست. ابزارهای ورودی خوبی برای کامپیوتر وجود داره که می‌تونه بهمون کمک کنه تا داده مورد نظر رو جمع‌آوری کنید.

گذشته از این، دوربین تلفن‌های همراه، می‌تونه منبع خوبی باشه برای جمع آوری تصاویر(پروژه‌های بینایی ماشین و …)، میکروفن‌های استودیویی برای دریافت صدا خوبن. اگر نیاز به دیتایی مثل گرما یا رطوبت نیاز دارید، طراحی مداری که این داده رو از محیط بخونه و روی دیتابیس خاصی ذخیره کنه کار سختی نیست.

جمع‌بندی

پروژه‌های هوش مصنوعی به ذات سخت نیستند. چیزی که اونها رو سخت می‌کنه، همین دیتای ورودی و تمیزکاری و مرتب کردنشه. بعضی وقتا داده‌های ما کم هستند و ما مجبور خواهیم شد که Data augmentation انجام بدیم. بعضی وقتا ممکنه نویز به قدری زیاد باشه که اصلا مرحله جمع‌آوری دیتا رو مجبور بشیم دوباره از نو انجام بدیم و … .

خلاصه هدف از این مطلب این بود که اگر پا در این عرصه گذاشتید، بدونید همیشه جایی هست که بتونید بدون مشکل، داده‌هایی رو دریافت و در پروژه‌تون استفاده کنید و از بابت نویز و …، خیالتون تا حد خوبی راحت باشه.

Share

مهندسی اجتماعی – هوشمندی متن‌باز (OSINT)، خبرسازی

در مطالب قبلی پیرامون مهندسی اجتماعی نوشتم. در اولین مطلب صرفا به این اشاره کردم که چیه و چرا مهمه، در مطلب دوم در مورد متد ماحی‌گیری نوشتم و در این مطلب، قراره دو روش دیگر مهندسی اجتماعی یعنی OSINT و همچنین خبرسازی رو با هم بررسی کنیم. اینجا، تقریبا می‌شه گفت که مباحث مهندسی اجتماعی تمام میشن و احتمالا در آینده جوانب دیگر امنیت سایبری رو با هم بررسی خواهیم کرد.

هوشمندی متن‌باز (OSINT)

همانطوری که در قسمت اول خدمت شما عرض کردم، ما در شبکه‌های اجتماعی و در کل در اینترنت خیلی از خودمون ردپا به جا میذاریم. هوشمندی‌ متن‌باز یا Open Source Intelligence دقیقا همینجا به کار هکرها میاد. روش کلاه‌سفیدش به نظر می‌تونه بررسی عقاید و سلایق مردم برای تولید محصول باشه (مثلا خواننده‌ها به ما پول بدند که در سلیقه موسیقی مردم فضولی کنیم و براشون تحلیل ارائه بدیم) و روش کلاه‌سیاهش می‌تونه این باشه که دیتای جمع‌آوری شده رو بهونه‌ای کنیم برای پرونده‌سازی و اخاذی از دیگران.

البته ما آدمای خوبی هستیم و چنین کاری نمی‌کنیم. ساختن پرونده هم به عهده مقامات امنیتی کشورها واگذار می‌کنیم چون اونها بهتر از ما بلدند و طبیعتا، راحتتر از ما می‌تونن چنین کاری کنند. اما اگر آدم بدی هستید هم به نظرم بهتره که برید تو اتاق و به کارای زشتتون فکر کنید جای این کارا 🙂

برای OSINT ابزارهای خوبی ساخته شده. در این پست من صرفا ابزارهایی که برای توییتر و اینستاگرام ساخته شدند رو یک بررسی ریز می‌کنم، اما اگر ابزار دیگری پیدا کردم احتمالا معرفی کنم. حواستون هم باشه استفاده از این ابزارها گرچه مانع قانونی نداره، اما اگر از داده‌های به دست آمده برای کاری مثل اخاذی یا پرونده‌سازی استفاده کنید مسیر رو برای شکایت کردن افراد از خودتان باز خواهید کرد.

توییتر

چند وقت پیش، در توییتر بحثی به نام «ابر کلمات» داغ بود. افرادی که دسترسی به API توییتر داشتند، برای افراد این ابر کلمات رو میساختند. اما من از اونجایی که حوصله نداشتم با توییتر نامه‌نگاری کنم، دنبال ابزاری بودم که حداقل توییت‌های حساب‌های حفاظت‌نشده رو به سادگی بتونه استخراج کنه. اونجا بود که با ابزار twint آشنا شدم (لینک). ابزار twint یا twitter intelligence ابزاریه که به شما کمک می‌کنه به سادگی در توییتر بچرخید و مثلا توییت‌های یک شخص رو استخراج کنید.

برای مثال، برای این که ۱۰۰ توییت آخر ریاست جمهوری آمریکا رو استخراج کنیم، کافیه دستور تویینت رو به این شکل اجرا کنیم:

twint -u potus --limit 100 -o potus.json --json

به این شکل، ما به سادگی به ۱۰۰ توییت آخر اون حساب کاربری دسترسی داریم.

البته می‌تونیم این دستور رو هی گسترش بدیم و ویژگی‌هایی مثل تاریخ، ساعت، مکان و … هم بهش اضافه کنیم. حالا این کجا به کارمون میاد؟ یه سناریوی خیلی ساده (که مربوط به بخش دوم همین مطلب هم میتونه بشه) رو در نظر بگیرید. مثلا قراره موز گران بشه. شما کافیه که twint رو به این شکل اجرا کنید:

twint -s "گرانی موز" --near Tehran --limit 1000

این هزار توییت آخری که مربوط به «گرانی موز» میشن رو برای ما لیست می‌کنه. می‌تونیم بفهمیم چه کسانی بهش دامن زدند و چه کسانی پیروی کورکورانه کردند و … . خلاصه که اتصال نقاط به یکدیگر خیلی راحتتر میشه.

اینستاگرام

برای اینستاگرام هم ابزارهایی وجود دارند که کمک کنند شما به سادگی بتونید در دیتایی که مردم به صورت حفاظت‌نشده (پابلیک یا عمومی) منتشر کردند بخزید و ببینید که دنیا دست کیه. OSINT در اینستاگرام، علاوه بر مقاصد خبیث (😂) می‌تونه به شدت بهتر برای مقاصد بازاریابی و تجاری استفاده بشه. چرا که بسیاری از مردم، در اینستاگرام به دنبال چیزایی که دوست دارند می‌گردند و خیلی‌ها هم حتی خریداشون رو از طریق اینستاگرام انجام می‌دن.

البته، اینستاگرام الگوریتم‌های عجیب و غریب زیاد داره و جدیدا APIش هم کمی سخت‌گیر تر شده. ابزاری که برای اینستاگرام پیدا کردم، اسمش هست Osintgram (لینک) و این ابزار رو متاسفانه فرصت نشده که تست کنم هنوز. اما، یک ویدئوی خوب از کانال NetworkChuck براش پیدا کردم که می‌تونید اینجا ببینیدش.

ابزارهای دیگر؟

صد در صد هزاران ابزار دیگر برای OSINT وجود دارند. من فقط میخواستم که مفاهیم پایه‌ش رو با هم بررسی کنیم و ببینیم که چی به چیه. در آینده، اگر ابزار خوبی برای OSINT پیدا کنم، حتما معرفی خواهم کرد چرا که لازمه بدونیم در دنیای اینترنت چطور می‌تونیم به سادگی تحت نظر باشیم. اونم نه تحت نظر افرادی که با تحت نظر گرفتن آدما، امنیتشون رو تامین می‌کنند، تحت نظر یه مشت دیوانه 🙂

خبرسازی

خبرسازی، یکی از راه‌های دیگر مهندسی اجتماعی، برای جا انداختن یک مفهوم یا یک ترس یا حتی طرفداری از شخصه. خبرسازی‌ها، معمولا از طرف یک نفر نیستند بلکه از طرف گروه‌ها انجام میشن. مثال کلاسیکش هم می‌تونه ماجرای فیسبوک و رباتهای روسی در جریان انتخابات امریکا باشه.حالا این خبرسازی‌ها به چه شکل صورت می‌گیره؟ معمولا یک الگوریتم خاصی رو داره. به جهت این که مثالش کمی ملموس‌تر باشه، از ترند «آهنربایی شدن بدن بعد دریافت واکسن» که تازگی‌ها خیلی روش مانور داده شد استفاده می‌کنم.

  • مرحله اول: یک نفر به قصد شوخی در پلتفرم‌های شوخی مثل تیک‌تاک، ویدئویی میذاره از این که اشیا فلزی بعد دریافت واکسن بهش می‌چسبن (لینک)
  • مرحله دوم: افرادی که می‌دونن این موضوع شوخیه، اون رو در شبکه‌های اجتماعی به نمایش میذارند.
  • مرحله سوم: اشخاصی که از ابتدا با موضوع واکسن مشکل داشتند، با زدن سر و ته (دقت کنید زدن سر و ته اینجا واقعا مهمه!) داستان، اون رو بازنشر میدن.
  • مرحله چهارم: توهمش در بسیاری از افراد به وجود میاد و یک سری خبر واقعی‌تر و غیرتیک‌تاکی ساخته میشه (لینک)
  • مرحله پایانی: افراد زیادی باور می‌کنند که چنین چیزی وجود داره …

حالا این خبر، از خبرهای میشه گفت شک‌برانگیز بوده. اما در همان مثال «گرانی موز» هم میشه اینطور خبرسازی کرد. البته خبرسازی معمولا روش‌های جلوگیری خوبی هم داره که در ادامه بهشون می‌پردازیم.

چطور بفهمیم که قربانی خبرسازی نشدیم؟

معمولا ما سواد رسانه‌ای بالایی نداریم. چون کارمون رسانه نیست. به همین خاطره که به راحتی می‌تونیم قربانی خبرسازی و اخبار جعلی – بخصوص در محیط شبکه‌های اجتماعی – بشیم. اول از همه زمان‌های بسیار قدیم یادمه که وبسایت درسنامه دوره‌ای برای این کار داشت اما متاسفانه ظاهرا این وبسایت دیگر در دسترس نیست (و در ویکی‌پدیا هم توضیح درستی نیست ازش) اما خب میشه با یک سری راه ساده فهمید که داستان چیه.

  • بپرسید. اگر افرادی رو می‌شناسید که در اون حوزه فعالن حتما بپرسید.
  • بررسی کنید. با همین ابزارهای OSINT می‌تونید خط فکری و طرفداری افرادی که یک خبر رو پخش کردند پیدا کنید. این به شما در قضاوت بهتر کمک می‌کنه.
  • واکنش‌سنجی کنید. واکنش مردم در این موارد واقعا مهمه، ببینید که اکثریت چه واکنشی می‌تونن نشون بدن. عمدتا این واکنش‌ها البته درست نیستند، اما می‌تونن سرنخ‌های خوبی به من و شما بدند.
  • در نهایت، از منابع خبری معتبر داخلی و خارجی استفاده کنید تا صحت خبر را بسنجید.

شاید این آخرین مطلب از سری اختصاصی «مهندسی اجتماعی» بود، اما باید یادمون باشه که همیشه این روش‌ها یکسان نیستند و در طول زمان می‌تونن به‌روز بشن. در واقع یادتون باشه، هر قفلی که ساخته بشه، یک قفل‌شکن هم براش پیش‌تر ساخته شده.

وظیفه ما، اینه که هم دیگر رو آگاه کنیم و به هم بگیم که چه چیزی ممکنه به ما در اینترنت آسیب بزنه یا در کل، ما رو در اینترنت عریان‌تر کنه. معرفی ابزارها و روش‌ها، صرفا به این خاطره که شما بتونید خودتون رو بررسی کنید و ببینید که چقدر دیتا ازتون موجوده و اگر راضی نیستید به وجودش، حتما برای حذفشون اقدام کنید.

خلاصه که متشکرم از وقتی که برای خوندن این مطلب گذاشتید. امیدوارم مفید واقع شده باشه.

همچنین بخوانید

Share

احراز هویت JWT در روبی آن ریلز

پس از مدت طولانی، با یک پست دیگر برگشتم و این بار قراره با هم احراز هویت JWT رو در ریلز بررسی کنیم. اول از همه، لازمه بدونیم JWT چیه؟ چرا نیازش داریم؟ اصلا چرا احراز هویت و هزاران چرای دیگر که احتمالا الان در سر شما هستند. بعدش یک پروژه خیلی کوچولو ایجاد می‌کنیم و با هم براش احراز هویت رو پیاده‌سازی می‌کنیم 🙂

احراز هویت JWT چیه و چرا بهش نیاز داریم؟

اول از همه این سوال بنیادی‌تر رو پاسخ بدیم که «چرا احراز هویت نیاز داریم؟» و بعد بریم سراغ احراز هویت JWT که قراره در این مطلب در موردش مفصل حرف بزنیم.

ما به احراز هویت نیاز داریم چون همیشه بخشی از داده‌های ما، خصوصی هستند. گذشته از اون، احراز هویت می‌تونه اجازه CRUD رو به شما بده، نه؟ فکر کنید اپی دارید که هرکسی می‌تونه روش بخونه و بنویسه. ممکنه خوندن چیزی باشه که برای «همه» مناسب باشه اما «نوشتن» اینطور نیست. بخصوص که نوشتن خودش به قسمت‌هایی مثل حذف و بروزرسانی هم شکسته شده.

پس ما به احراز هویت نیاز داریم که هر ننه‌قمری (😂) نتونه از API ما استفاده کنه. بلکه کاربرانی که ثبت‌نام کردند و دسترسی درستی به سرویس دارند، بتونن استفاده کنن. این قضیه در API های تجاری (یا Business facing) خودشون رو بیشتر و بهتر نشون میدن.

حالا سوال مهم‌تر …

احراز هویت JWT چیه؟

در اپهای قدیمی (مثل همین وردپرس)، احراز هویت توسط cookie ها انجام میشه. به چه صورتی؟ به این صورت که وقتی نام کاربری و گذرواژه وارد می‌کنیم، نرم‌افزار فضایی رو در مرورگر به خودش اختصاص میده و یک سری اطلاعات رو با خودش جابجا می‌کنه. اما در ReST API ها این قضیه رو نداریم. در واقع نمی‌تونیم به کوکی‌ها اعتماد کنیم. پس چه می‌کنیم؟ اینجا لازمه جز یوزرنیم(که معمولا می‌تونه عمومی باشه) و پسورد (که می‌تونه راحت لو بره) میاییم و یک «توکن» هم تعریف می‌کنیم. این توکن، می‌تونه ثابت یا متغیر باشه. یعنی چی؟ یعنی می‌تونه به ازای هربار ورود تغییر کنه، می‌تونه سر زمان مشخصی هم منقضی بشه.

حالا توکن چیه؟ توکن به صورت کلی، در کازینوها معادل پولیه که شما در بازی‌ها قرار می‌دید، در واقع مجوز حضور شما در اون کازینو، کلاب و … است. حتی به رمزارزهایی که بر مبنای دیگر رمزارزها ساخته میشن هم سکه نمی‌گن بلکه میگن توکن. شما فرض کنید که مثلا ۱۰۰ دلار می‌دید و پنج تا سکه با آرم اون کازینوی خاص دریافت می‌کنید. اگر در بازی برنده بشید یا ببازید، باید توکن‌هاتون رو تحویل بدید یا بگیرید.

حالا در احراز هویت JWT هم، ما به ازای کاربرمون یک توکن در نظر می‌گیریم. این توکن، معمولا یک رشته طولانیه که انسان نمی‌تونه بخوندش. نتیجتا خیلی از اطلاعات ما به صورت ایمن‌تر می‌تونن رد و بدل بشن (طبیعیه که مواردی مثل SSL داشتن و الگوریتم‌هایی که در ساخت توکن داشتیم هم مهمن). ضمن این که نام‌کاربری، ایمیل، رمزعبور و .. هم به همین سادگیا نمی‌تونن خونده بشن.

پس ما می‌آییم و یک دیتابیسی از توکن‌ها در کنار دیتابیسی از یوزرها میسازیم (البته درست‌ترش، جدوله!) و به ازای هر یوزر معمولا دوتا توکن در اون دیتابیس قرار می‌دیم. یکیش رو بهش میگیم «توکن دسترسی» یا Access Token و یکی رو می‌گیم «توکن بازنشانی» یا Refresh Token. توکن دسترسی، معمولا یک تاریخ انقضایی داره و بعد از اون با استفاده از توکن بازنشانی، می‌تونیم یکی جدید بگیریم. اما در آموزش امروز، صرفا میخوایم توکن دسترسی رو به دست بیاریم.

شمایی از کار JWT
احراز هویت JWT به این شکل کار می‌کنه

خب، الان که تقریبا همه‌چی رو می‌دونیم، بریم برای پیاده‌سازی.

پیاده‌سازی یک اپلیکیشن ریلز با JWT

خب در قدم اول، باید یک اپ ایجاد کنیم. این اپ رو به این شکل ایجاد می‌کنیم:

rails new devise-jwt --api

خب توضیح واضحات:

  • قسمت rails که واضحا فراخوانی نرم‌افزار rails در ترمینال ماست.
  • قسمت new در خواست برای ایجاد یک اپ جدیده.
  • قسمت devise-jwt اسم پروژه ماست. حالا چرا؟ چون قراره از یک لایبرری با همین اسم استفاده کنیم. بنابراین، پروژه رو اینطوری اسم گذاشتیم.
  • در قسمت آخر هم، به ریلز گفتیم که ما تو رو بخاطر API هات دوست داریم. ویو نیاز نیست.

بعد از چند ثانیه (و بسته به سرعت اینترنت دقیقه) اپ ما ساخته می‌شه. بعد لازمه که مرحله مرحله کارهایی رو انجام بدیم.

نصب لایبرری‌های مورد نیاز

خب، اول از همه با ویرایشگر متنی مورد علاقمون فایل Gemfile رو باز می‌کنیم و این خطوط رو بهش اضافه می‌کنیم :
gem 'devise'
gem 'devise-jwt'
gem 'rack-cors'

بعد از این که این خطوط رو اضافه کردیم، دستور زیر رو اجرا می‌کنیم:

bundle

این دستور چه کار می‌کنه؟ میاد و تمام لایبرری‌های مورد نظر شما رو به صورت ایزوله در یک دایرکتوری، نصب می‌کنه. به این شکل شما می‌تونید به سادگی بدون رسیدن آسیب به باقی لایبرری‌های روبی نصب شده روی سرور یا حتی کامپیوتر خودتون، ایده‌هاتون رو تست کنید.

لازم به ذکره که بعد از اجرای این دستور فایل Gemfile.lock به‌روز میشه، این فایل حالا چه کار می‌کنه؟ این فایل حواسش به همه‌چی هست. در واقع، ورژن روبی، ورژن ریلز، لایبرری‌های مورد نیاز و ورژنینگشون و … رو همه رو این فایل داره کنترل می‌کنه.

بعد از انجام مراحل فوق، کافیه این دستور هم اجرا کنیم:

rails g devise:install

این دستور چه می‌کنه؟ این دستور هم برای ما فایلهای devise رو در جای درستش قرار می‌ده.

آشنایی با devise

برای احراز هویت در هر سیستمی ما دو راه داریم:

  • نوشتن سیستم احراز هویت از بیخ
  • استفاده از کتابخانه‌های موجود

در مورد روش «از بیخ»، ما معمولا این کار رو انجام نمی‌دیم. چرا؟ چون معمولا اونقدر خوب نیستیم که بتونیم امنیت سیستم رو به خوبی تامین کنیم. در مورد دوم، در هر فرمورک و زبانی، کتابخانه‌هایی ساخته شدند که کمک می‌کنن ما بتونیم با اضافه کردنشون به پروژه خودمون، بخش احراز هویت رو هندل کنیم. برای ریلز devise ساخته شده. این لایبرری، یک لایبرری مبتنی بر cookie برای احراز هویت وب‌اپ‌هاست.

بعد از همه‌گیر شدن ReST API ها، لایبرری devise-jwt هم نوشته شد. این لایبرری، ابزاریه که به من و شما کمک می‌کنه بتونیم احراز هویت JWT رو به پروژه‌مون اضافه کنیم. در واقع هر سه لایبرری که به پروژه اضافه کردیم، کارشون همینه که JWT رو برای ما راحت کنند.

هندل کردن CORS

در این مطلب قصد ندارم در مورد CORS حرف بزنم، چون قبل‌تر ازش حرف زدم (و می‌تونید اینجا بخونید). اینجا ما صرفا قصدمون اینه که بیاییم و این مشکل رو حل کنیم. چطوری؟ خب این فایل:

config/initializers/cors.rb

رو با ویرایشگر متنی مورد علاقه‌مون باز می‌کنیم، و محتواش رو به این شکل تغییر می‌دیم:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'

    resource '*',
             headers: :any,
             methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

توجه کنید که این قسمت معمولا به صورت کامنت‌شده در کد هست، فقط کافیه آنکامنتش کنید و نیاز نیست که کلا این مورد رو کپی پیست کنید.

ساخت مدل و کنترلرهای مورد نیاز برای کاربر

یکی از خوبی‌های devise اینه که به شکل scaffold گونه‌ای، می‌تونه به ما کمک کنه که کاربر و سیستم کنترلش رو بسازیم. برای ساخت مدل کاربر فقط کافیه که این دستور رو اجرا کنیم:

rails g devise User

به این شکل می‌فهمه که باید یک مدل، مطابق مدل User ولی با مشخصات devise برامون بسازه. بعدش هم کافیه این دستور رو اجرا کنیم:

rails db:migrate

که جدولای مرتبط برامون در دیتابیس ساخته بشن.

حالا که خیالمون از بابت این قضایا راحت شد چی؟ هیچی. دو تا کنترلر هم می‌سازیم به این شکل:

rails g controller users/sessions
rails g controller users/registrations

بعد از این میشه گفت که کار ما اینجا تمام شده و باید بریم یه چیزایی رو ادیت کنیم 🙂

ویرایش مدل یوزر

بعد از این که کارهای بالا رو انجام دادیم، کافیه که بریم سراغ مدل یوزرمون و به این شکل ادیتش کنیم:

class User < ApplicationRecord

  devise :database_authenticatable,
         :jwt_authenticatable,
         :registerable,
         jwt_revocation_strategy: JwtDenylist
end

حالا این کار برای چیه؟ برای اینه که ما یک جدول دیگر به اسم JWT Deny List در نظر می‌گیریم و توکن‌های منقضی‌شده رو درونش قرار می‌دیم. به اون شکل وقتی توکنی منقضی بشه، می‌تونیم به کاربر خطا نشون بدیم یا از توسعه‌دهنده‌های فرانت تیم بخوایم که وقتی اون خطا رو دیدن، کاربر رو لاگ اوت کنن. خلاصه که راه برای رسیدن به نتیجه مطلوب زیاده. بگذریم، بعد از این، در پوشه مدلها لازمه که یک فایل به اسم jwt_denylist.rb ایجاد کنیم و این محتوا رو درونش قرار بدیم:

class JwtDenylist < ApplicationRecord
  include Devise::JWT::RevocationStrategies::Denylist

  self.table_name = 'jwt_denylist'
end

بعد نیاز داریم که برای این قضیه یک مایگرشن اضافه کنیم:

rails g migration CreateJwtDenylist

سپس، فایل مایگرشن که معمولا در آدرس:

db/migrate

قرار داره رو باز می‌کنیم و محتواش رو به این شکل تغییر می‌دیم:

class CreateJwtDenylist < ActiveRecord::Migration[6.1]
  def change
    create_table :jwt_denylist do |t|
      t.string :jti, null: false
      t.datetime :exp, null: false
    end
    add_index :jwt_denylist, :jti
  end
end

و بعد یک دور مایگرشن‌ها رو اجرا می‌کنیم:

rails db:migrate

تا اینجا مطلب طولانی شد؟ ایرادی نداره. بریم یک قهوه بزنیم به بدن و برگردیم 🙂

کنترلر Session

امیدوارم که کافئین به قدر کافی مودتون رو بالا آورده باشه 🙂 حالا وقتشه که بریم و کنترلر session رو درست کنیم. نیازی نیست واقعا کار خاصی کنیم. تنها کاری که نیازه بکنیم اینه که کنترلری که ساختیم رو باز کنیم و این موارد رو درش کپی کنیم:

class Users::SessionsController < Devise::SessionsController
  respond_to :json

  private

  def respond_with(resource, _opts = {})
    render json: { message: 'You are logged in.' }, status: :ok
  end

  def respond_to_on_destroy
    log_out_success && return if current_user

    log_out_failure
  end

  def log_out_success
    render json: { message: "You are logged out." }, status: :ok
  end

  def log_out_failure
    render json: { message: "Hmm nothing happened."}, status: :unauthorized
  end
end

نکته مهم، اگر هنگام ساخت کنترلر، جای users از چیز دیگری استفاده کردید باید Users رو در کد بالا به اون تغییر بدید. اگر هم کلا چیزی نذاشتید، کل قسمت Users:: رو ازش حذف کنید.

کنترلر Registration

خب عین همون بخش قبلی، شما کافیه کنترلر registrations رو باز کنید و این کد رو درونش کپی کنید:

class Users::RegistrationsController < Devise::RegistrationsController
  respond_to :json

  private

  def respond_with(resource, _opts = {})
    register_success && return if resource.persisted?

    register_failed
  end

  def register_success
    render json: { message: 'Signed up sucessfully.' }
  end

  def register_failed
    render json: { message: "Something went wrong." }
  end
end

تنظیمات نهایی devise

خب اول در ترمینال (یا cmd) این دستور رو اجرا کنید:

rake secret

و یک کد طولانی و مسخره بهتون میده 😁 اون رو در فایل:

config/initializers/devise.rb

در آخر فایل به این شکل کپی کنید:

config.jwt do |jwt|
  jwt.secret = rake_secret_output
end

نکته بسیار مهم اینجا چیه؟ این که حواستون باشه این صرفا یک پروژه تسته و برای محیط پروداکشن اصلا جالب نیست که سیکرت‌ها و توکن‌ها، هاردکد باشن. برای اون زمان می‌تونید از ENV استفاده کنید.

مسیرها

خب، الان که تقریبا همه‌چی آرومه و ما چقدر خوشحالیم، کافیه که بیاییم و فایل routes.rb رو هم به این شکل ویرایش کنیم:

Rails.application.routes.draw do
  devise_for :users,
             controllers: {
                 sessions: 'users/sessions',
                 registrations: 'users/registrations'
             }
end

خب پس چی‌ می‌مونه که انجام ندادیم؟ یک سری آزمایش ساده 🙂

ساخت کاربر

خب الان کافیه بعد اجرای سرور ریلز (مطابق آموزش‌های قبلی)، این دستور رو اجرا کنیم:

curl -X POST -H "Content-type: application/json" -d '{ "user": { "email":"test@test.com", "password":"12345678", "password_confirmation":"12345678"}}' http://localhost:3000/users

بعد از اجرای این دستور، یک شیء جی‌سون ساده به این شکل:

{"message":"Signed up sucessfully."}

به ما برمی‌گرده.

دریافت توکن

حالا چطور توکن دریافت کنیم؟ این هم ساده‌ست. فقط کافیه که این دستور رو اجرا کنیم:

curl -X POST -i -H "Content-type: application/json" -d '{"user":{"email":"test@test.com", "password":"12345678"}}' http://localhost:3000/users/sign_in

بعد در خروجی اول به ما چنین چیزی می‌ده:

HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: application/json; charset=utf-8
Vary: Accept, Origin
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIyIiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNjIyMTAyOTUxLCJleHAiOjE2MjIxMDY1NTEsImp0aSI6IjBlZDk0YTFmLTgzYTEtNDM3Yy1hOTBkLWQyNTNjY2ZlZDE5YyJ9.NohABuynT-F2GqfCscGtSF6zzK0iAVUIlajSqmMgIMA
ETag: W/"36cb9f6def08029b9c6bff3c14a98017"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 0584c92c-5100-4acf-8a21-852faa1c0173
X-Runtime: 0.209443
Transfer-Encoding: chunked

که این‌ها سرایند (Header) های ما هستند. در این قسمت، هرچی جلوی Authorization قرار داره توکن ماست. و می‌تونیم ازش استفاده کنیم.

بخش بعدی هم اینه :

{"message":"You are logged in."}

که صرفا به ما می‌گه ورودمون موفقیت‌آمیز بوده.

فکر کنم این مطلب، آخرین مطلبی بود که در مورد بیسیک‌های روبی‌آن‌ریلز می‌نوشتم. احتمالا در آینده نه‌چندان دور، همه این‌ها رو با هم به یک سری آموزش ویدئویی تبدیل کنم و از طریق آپارات یا یوتوب منتشرشون کنم.

طبیعتا یک قسمت‌هایی از آموزش در این مطلب پوشش داده نشده، سعی می‌کنم در آینده یک یا دو پست تکمیلی هم ارائه کنم که همه این قضایا به خوبی پوشش داده بشه (یا این که کلا در بخش ویدئویی در خدمتتون باشم).

به صورت کلی، دوست دارم بدونم نظر شما در مورد این تیپ آموزش‌ها چیه؟ آیا ادامه‌شون بدم یا خیر؟ و این که آیا پایه‌ش هستید که بحث فرانتند رو هم شروع کنیم یا روی همین بکند باقی بمونیم و اول یه پروژه کامل رو بکندش رو بزنیم و بعد بریم سراغ فرانت؟ 🙂

در آخر هم بابت وقتی که گذاشتید و مطلب رو خوندید ازتون متشکرم.

Share

ساخت REST API در روبی آن ریلز – قسمت دوم

در پست قبلی با هم یک REST API نوشتیم که یک نمونه از مدل «پست» رو می‌تونست ایجاد کنه، بروز کنه، نمایش بده و نابود کنه.

در این پست هم قصد دارم که کار مشابهی کنم، منتها این بار تیم محصول به ما یک سناریوی جدید داده. از ما خواستند که این بار، کامنت هم به پست‌ها اضافه کنیم و بتونیم با استفاده از API برای هرپستی، یک کامنت هم ایجاد کنیم. پس وقت رو غنیمت می‌شماریم و میریم سروقت پروژه (پوشه‌ها و ساختار عینا مثل پست قبلیه و هیچ تغییری در اون رخ نداده).

ساخت مدل برای کامنت

بیاییم ببینیم تیم محصول برای ما چی طراحی کرده. این عزیزان در نظر دارند که هر کامنت صرفا یک «متن بدنه» داشته باشه و بیشتر از اون نیاز نداشتند. کار ما اینه که حالا مدلی طراحی کنیم که علاوه بر اون، به پست‌ها هم ربط داشته‌باشه. چطوری این کار رو می‌تونیم بکنیم؟

کافیه دستور زیر رو اجرا کنیم و مدلش رو بسازیم:

rails generate model Comment body:text post_id:integer

خب حالا میریم به پوشه :

app/models

و اول post.rb رو به این شکل ویرایش می‌کنیم:

class Post < ApplicationRecord
    has_many :comments 
end

و سپس comment.rb رو به این شکل ویرایش می‌کنیم:

class Comment < ApplicationRecord
    belongs_to :post 
end

حالا این خطوط چی میگن؟ ما در پایگاه داده چندین نوع رابطه داریم. توضیح این روابط به صورت مفصل باشه برای یک پست دیگه. اما اینجا بیاید در نظر بگیرید که طراحی محصول به شکلی بوده که «هر پست میتونه بی‌شمار کامنت داشته باشه و هر کامنت متعلق به فقط و تنها فقط یک پسته». این نوع رابطه اسمش هست «یک به چند» یا بهتر بگم «یک به خیلی» و به قول خارجی‌ها One to many.

حالا که از این قضیه خبر داریم و پست رو هم ساختیم تعلل نمی‌کنیم. می‌ریم سراغ ساخت کنترلر مربوطه. اینجا کنترلر به ما کمک می‌کنه که بتونیم به سادگی یک کامنت رو روی پست بسازیم و مدیریت کنیم. در مورد سناریوی کنترل کامنت هم این بار کمی ساده‌تر می‌گیریم. در ادامه این مورد رو با هم بررسی خواهیم کرد.

ساخت کنترلر کامنت

اول کنترلر کامنت رو به این شکل ایجاد می‌کنیم:

rails generate controller api/v1/comments

و سپس در فایل:

config/routes.rb

این تغییر ریز رو ایجاد می‌کنیم :

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :post do 
        resources :comments
      end
    end
  end
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

و بعد میریم سروقت کنترلر 🙂 اما قبل از اون بیاید یه چیزی رو بررسی کنیم. این روابط رو! این روابط چطوری تعیین شدند؟ و چرا مهمند. پس در ترمینالمون تایپ می‌کنیم:

rails c

این دستور، به ما یک «کنسول ریلز» میده. کنسول به ما کمک می‌کنه که ایده‌ها رو در یک لول قبل از مرورگر و درخواست‌های HTTP بررسی کنیم. در اسکرین‌شات زیر از ترمینال من، می‌بینید که چطوری یکی از پست‌ها رو تست کردم و دیدم که آیا روابطش با کامنت‌ها درسته یا خیر.

خب حالا بیاییم کنترلر رو بنویسیم. قبل از اون، من یک کامنت دستی در کنسول به این شکل می‌سازم:

c = Comment.new(:body => "This is a comment", :post_id => 1)
c.save

و کنسول رو می‌بندم. می‌ریم سراغ کنترلرمون. همونطور که گفتم اینجا یه سری چیزا نیستن. مثلا show اینجا نیازی نیست باشه ولی index نیاز هست. پس می‌ریم سراغ این که این موارد رو در کنترلر لحاظ کنیم. خب با توجه به این توضیحات، ما یک متد index به این شکل نیاز داریم:

def index
    @post = Post.find(params[:post_id])
    render json: @post.comments
end

همونطور که دیدید، اینجا تنها چیزی که نیازه بررسی بشه post_id ماست. درخواستی که به سمت سرور می‌فرستیم هم به این شکله:

curl -X GET -i http://localhost:3000/api/v1/post/1/comments

حالا وقتشه که بتونیم یک کامنت جدید ایجاد کنیم. برای ساخت کامنت جدید هم کافیه که به این شکل، متد create رو بنویسیم:

def create
        @comment = Comment.new(:body => params[:comment][:body], :post_id => params[:post_id])
        if @comment.save 
            render json: {:status => "success", :comment => @comment}
        end 
    end

و نمونه درخواستی که براش می‌فرستیم هم به این شکل:

curl -X POST -H 'Content-Type: application/json' -i http://localhost:3000/api/v1/post/1/comments --data '{
"body":"This is another comment"
}'

حالا یک سوال مهم ممکنه برای شما پیش بیاد و اون هم اینه که :

چرا پارامترهای ارسالی فرق دارند؟

دلیلش خیلی ساده‌ست. ریلز اول میاد پارامترهای درون URL رو مستقیم میخونه، بعد میاد سراغ Request Body که در واقع اگر سلسله مراتبی (مثل یک فایل YAML) بهش نگاه کنیم این شکلی میشه:

- post_id: 1
- comment:
    - body: "This is another comment"

در واقع برای خودش یک Resource space در نظر می‌گیره و body رو از اون میخونه. به همین خاطره که یکی زیرمجموعه comment و دیگری مستقیما post_id میشه.

باقی متدها چی؟

معمولا کامنت‌ها قابل ادیت و حذف و … نیستند. ما هم به جهت سادگی این ماجرا رو براشون پیاده‌سازی نمی‌کنیم تا بعدا چه پیش آید 🙂

جمع‌بندی دو قسمت اخیر

خب در این دوقسمت ما خیلی چیزا یاد گرفتیم که فهرست‌وار بررسی می‌کنیم :

  • چطور ریلز نصب کنیم.
  • چطور یک پروژه ریلز جدید ایجاد کنیم.
  • چطور یک منطق تجاری (Business Logic) رو درک کنیم
  • چطور مدل‌های مورد نظر رو بسازیم
  • چطور API بسازیم و تست کنیم.

این موارد بسیار مهمن و فکر کنم بعد خوندن این دو قسمت حداقل‌های ساخت یک API رو یاد گرفتید. بعد از این چه چیزهایی لازمه که یاد بگیریم؟ این دیگه بستگی به خودتون داره. شاید در موردش مطلبی بنویسم اما فکر کنم این آخرین مطلبیه که انقدر مستقیم داره به نوشتن و ساختن API اشاره می‌کنه.

در مطالب بعدی، میخواهیم بریم سراغ یک سری مفهوم و پیاده‌سازی دیگر. احتمال قوی هم بریم سراغ فرانتند و ببینیم که در دنیای فرانتند چه خبره. پس منتظر باشید که فصل جدیدی از مطالب فنی در راهه 🙂

در آخر، از شما بابت وقتی که برای خوندن این مطلب گذاشتید هم کمال تشکر رو دارم.

Share