اولین برنامه Computer Vision خود را در Android یا iOS بسازید

1. قبل از شروع

در این لبه کد، نحوه ساخت اپلیکیشنی را بررسی خواهید کرد که با استفاده از کیس اصلی Computer Vision، محتویات اولیه یک تصویر را شناسایی کند. این معمولاً طبقه بندی تصویر یا برچسب گذاری تصویر نامیده می شود.

پیش نیازها

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

چیزی که خواهی ساخت

  • یک برنامه اندرویدی که قادر به طبقه بندی تصویر یک گل است
  • (اختیاری) یک برنامه iOS که قادر به طبقه بندی تصویر یک گل است

آنچه شما نیاز دارید

  • Android Studio، موجود در https://developer.android.com/studio برای بخش Android Codelab
  • Xcode، موجود در فروشگاه App Apple، برای بخش iOS از Codelab

2. شروع کنید

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

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

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

برای ساده نگه داشتن برنامه تا حد امکان، از تصاویر همراه با آن به عنوان منابع استفاده می کند و طبقه بندی آنها را به شما نشان می دهد. برنامه های افزودنی آینده می تواند استفاده از Image Picker یا کشیدن تصاویر به طور مستقیم از دوربین باشد.

شما با گذراندن مراحل ساخت برنامه در اندروید با استفاده از Android Studio شروع خواهید کرد. (برای انجام این کار در iOS به مرحله 7 بروید.)

  1. Android Studio را باز کنید، به منوی File بروید و Create a New Project را انتخاب کنید.
  2. از شما خواسته می شود که یک الگوی پروژه را انتخاب کنید. Empty Activity را انتخاب کنید.

859b1875e37c321a.png

  1. روی Next کلیک کنید. از شما خواسته می شود که پروژه خود را پیکربندی کنید . هر نام و نام بسته ای را که می خواهید به آن بدهید، اما کد نمونه در این لبه کد از نام پروژه ImageClassifierStep1 و نام بسته com.google.imageclassifierstep1 استفاده می کند.

ee3b6a81bad87b3.png

  1. زبان مورد نظر خود را انتخاب کنید، کوتلین یا جاوا. این آزمایشگاه از Kotlin استفاده می کند، بنابراین اگر می خواهید دقیقاً دنبال کنید، احتمالاً می خواهید Kotlin را انتخاب کنید.
  2. وقتی آماده شد، روی Finish کلیک کنید. Android Studio برنامه را برای شما ایجاد می کند. تنظیم همه چیز ممکن است چند لحظه طول بکشد.

3. کتابخانه برچسب‌گذاری تصویر کیت ML را وارد کنید

ML Kit (https://developers.google.com/ml-kit) راه‌حل‌هایی را برای توسعه‌دهندگان ارائه می‌دهد که با سناریوهای رایج در یادگیری ماشین مواجه می‌شود و پیاده‌سازی و کار بر روی پلتفرم را آسان می‌کند. ML Kit یک کتابخانه کلید در دست ارائه می دهد که می توانید در این برنامه به نام Image Labelling از آن استفاده کنید. این کتابخانه شامل مدلی است که برای تشخیص بیش از 600 کلاس تصویر از قبل آموزش داده شده است. به این ترتیب، برای شروع عالی است.

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

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

  1. در Android Studio، با استفاده از کاوشگر پروژه، مطمئن شوید که Android در بالا انتخاب شده است.
  2. پوشه Gradle Scripts را باز کنید و فایل build.gradle را برای برنامه انتخاب کنید. ممکن است 2 یا بیشتر وجود داشته باشد، بنابراین اطمینان حاصل کنید که از سطح یک برنامه همانطور که در اینجا نشان داده شده است استفاده می کنید:

93c2e157136671aa.png

  1. در پایین فایل، بخشی به نام وابستگی ها را می بینید که در آن لیستی از تنظیمات implementation ، testImplementation و androidImplementation ذخیره می شود. با این کد یک فایل جدید به فایل اضافه کنید:
implementation 'com.google.mlkit:image-labeling:17.0.3'

(مطمئن شوید که این در داخل وابستگی های { } است)

  1. می‌بینید که نواری در بالای پنجره ظاهر می‌شود که نشان می‌دهد build.gradle تغییر کرده است، و باید دوباره همگام‌سازی کنید. برو و این کار را بکن. اگر آن را نمی‌بینید، به دنبال نماد فیل کوچک در نوار ابزار بالا سمت راست بگردید و روی آن کلیک کنید.

5ef40c7a719077a0.png

اکنون کیت ML را وارد کرده‌اید و آماده شروع برچسب‌گذاری تصویر هستید.

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

4. رابط کاربری را بسازید

در Android Studio، با استفاده از یک فایل طرح‌بندی مبتنی بر xml، رابط کاربری را برای هر صفحه (یا Activity) ویرایش می‌کنید. برنامه اصلی که ایجاد کردید یک اکتیویتی دارد (که کد آن در MainActivity است و به زودی آن را خواهید دید)، و اعلان رابط کاربری در activity_main.xml است.

می توانید این را در پوشه res > layout در پروژه اکسپلورر اندروید پیدا کنید - مانند این:

3ed772e9563061e9.png

با این کار یک ویرایشگر کامل باز می شود که به شما امکان می دهد رابط کاربری Activity خود را طراحی کنید. چیزهای زیادی در آنجا وجود دارد، و هدف این آزمایشگاه این نیست که به شما نحوه استفاده از آن را بیاموزد. برای کسب اطلاعات بیشتر در مورد ویرایشگر طرح بندی، به این آدرس مراجعه کنید: https://developer.android.com/studio/write/layout-editor

برای اهداف این آزمایشگاه، ابزار Code را در گوشه سمت راست بالای ویرایشگر انتخاب کنید.

1f7dbdef48d9ade6.png

اکنون فقط کد XML را در قسمت اصلی پنجره خواهید دید. کد را به این تغییر دهید:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/imageToLabel"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/btnTest"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Label Image"
            android:layout_gravity="center"/>
        <TextView
            android:id="@+id/txtOutput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:gravity="start|top" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

این به شما یک طرح بسیار ساده شامل ImageView (برای نمایش تصویر)، یک Button (برای فشار دادن کاربر) و یک TextView می دهد که در آن برچسب ها نمایش داده می شوند.

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

5. تصاویر را با برنامه دسته بندی کنید

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

  1. در کاوشگر پروژه، در برنامه در بالا، کلیک راست کرده و New Directory را انتخاب کنید.
  2. در محاوره‌ای که با فهرستی از فهرست‌های راهنما ظاهر می‌شود، src/main/assets را انتخاب کنید.

c93650ea68bb60e9.png

پس از انجام این کار، یک پوشه دارایی جدید در کاوشگر پروژه ظاهر می شود:

444b4afab73433b8.png

  1. روی این پوشه کلیک راست کنید و پنجره ای با لیستی از گزینه ها مشاهده خواهید کرد. یکی از این موارد باز کردن پوشه در سیستم فایل شما خواهد بود. مناسب برای سیستم عامل خود را پیدا کنید و آن را انتخاب کنید. (در مک این گزینه Reveal در Finder ، در ویندوز Open در Explorer و در اوبونتو نمایش در فایل ها خواهد بود.)

95e0eca881d35f6b.png

  1. یک فایل را در آن کپی کنید. می توانید تصاویر را از سایت هایی مانند Pixabay دانلود کنید. تغییر نام تصویر به چیزی ساده توصیه می شود. در این مورد، تصویر به flower1.jpg تغییر نام داده است.

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

cfa53c9c75a033d8.png

اکنون آماده هستید که این تصویر را برچسب گذاری کنید!

6. کد طبقه بندی را برای برچسب گذاری تصویر بنویسید

(و اکنون بخشی که همه منتظرش بودیم، انجام Computer Vision در اندروید!)

  1. شما کد خود را در فایل MainActivity می نویسید، پس آن را در پوشه پروژه در زیر com.google.devrel.imageclassifierstep1 (یا هر فضای نام معادل شما در صورت انتخاب نام دیگری است) پیدا کنید. توجه داشته باشید که معمولاً 3 پوشه فضای نام در پروژه Android Studio تنظیم شده است، یکی برای برنامه، یکی برای Android Test و دیگری برای تست. MainActivity خود را در اکتیویتی خواهید یافت که بعد از آن توضیحاتی در داخل پرانتز وجود ندارد.

b5aef8dd5e26b6c2.png

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

  1. فایل MainActivity را باز کنید و یک فایل کلاسی به نام MainActivity را در ویرایشگر کد خواهید دید. می بایست شبیه به این باشه:
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

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

  1. این کد را اضافه کنید:
// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName: String): Bitmap?{
    return try {
        with(assets.open(fileName)){
            BitmapFactory.decodeStream(this)
        }
    } catch (e: IOException) { null }
}

اندروید استودیو احتمالاً در این مرحله شکایت خواهد کرد و برخی از کدها را با رنگ قرمز برجسته می کند، مانند Context ، Bitmap و IOException :

d2bde17e3c04aeed.png

نگران نباش! این به این دلیل است که شما هنوز کتابخانه‌هایی را که حاوی آنها هستند وارد نکرده‌اید. Android Studio یک میانبر مفید ارائه می دهد.

  1. مکان نما خود را روی کلمه بکشید و ALT + Enter ( Option + Enter در مک) را فشار دهید تا import برای شما ایجاد شود.
  2. سپس می‌توانید بیت مپ را از دارایی‌ها بارگیری کنید و آن را در ImageView قرار دهید. به onCreateFunction MainActivity برگردید، این کد را درست زیر خط setContentView اضافه کنید:
val img: ImageView = findViewById(R.id.imageToLabel)
// assets folder image file name with extension
val fileName = "flower1.jpg"
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
    img.setImageBitmap(this)
}
  1. مانند قبل، برخی از کدها با رنگ قرمز برجسته خواهند شد. مکان نما را روی آن خط قرار دهید و از Alt + Enter / Option + Enter برای اضافه کردن خودکار واردات استفاده کنید.
  2. در فایل layout.xml که قبلا ایجاد کردید، نام imageToLabel را به ImageView داده‌اید، بنابراین خط اول نمونه‌ای از یک شی ImageView به نام img را با استفاده از آن اطلاعات طرح‌بندی ایجاد می‌کند. با استفاده از findViewById ، یک تابع داخلی اندروید، جزئیات را پیدا می کند. سپس از نام فایل flower1.jpg برای بارگذاری تصویر از پوشه دارایی ها با استفاده از تابع assetsToBitmap که در مرحله قبل ایجاد کردید استفاده می کند. در نهایت، از کلاس انتزاعی بیت مپ برای بارگذاری بیت مپ در img استفاده می کند.
  3. فایل طرح‌بندی دارای یک TextView بود که برای نمایش برچسب‌هایی که برای تصویر استنباط شده‌اند استفاده می‌شود. یک شی کد برای آن بعدی دریافت کنید. بلافاصله زیر کد قبلی، این را اضافه کنید:
val txtOutput : TextView = findViewById(R.id.txtOutput)

همانطور که قبلاً، این اطلاعات فایل طرح بندی را برای نمای متنی با استفاده از نام آن پیدا می کند (XML را که txtOutput نامیده می شود بررسی کنید) و از آن برای نمونه سازی یک شی TextView به نام txtOutput استفاده می کند.

به طور مشابه، یک شیء دکمه برای نمایش دکمه ایجاد می‌کنید و آن را با محتوای فایل طرح‌بندی نمونه‌سازی می‌کنید.

در فایل layout دکمه را btnTest ، بنابراین می‌توانیم آن را به صورت زیر نمونه‌سازی کنیم:

val btn: Button = findViewById(R.id.btnTest)

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

قبل از ادامه، مطمئن شوید که کد onCreate شما به شکل زیر است:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val img: ImageView = findViewById(R.id.imageToLabel)
    // assets folder image file name with extension
    val fileName = "flower1.jpg"
    // get bitmap from assets folder
    val bitmap: Bitmap? = assetsToBitmap(fileName)
    bitmap?.apply {
        img.setImageBitmap(this)
    }
    val txtOutput : TextView = findViewById(R.id.txtOutput)
    val btn: Button = findViewById(R.id.btnTest)
}

هیچ یک از کلمات کلیدی نباید قرمز رنگ باشد که نشان می دهد هنوز وارد نشده اند. اگر آنها هستند، لطفاً به عقب برگردید و ترفند ALT + Enter را برای تولید واردات انجام دهید.

هنگام استفاده از برچسب تصویر ML Kit، اولین قدم معمولاً ایجاد یک شی Options برای سفارشی کردن رفتار است. شما تصویر خود را به فرمت InputImage تبدیل خواهید کرد که ML Kit بتواند آن را تشخیص دهد. سپس یک شی Labeler برای انجام استنتاج ایجاد می کنید. این یک تماس ناهمزمان با نتایج به شما می دهد که سپس می توانید آن را تجزیه کنید.

روی دکمه‌ای که ایجاد کردید، همه این کارها را در رویداد onClickListener انجام دهید. این هم کد کامل:

btn.setOnClickListener {
  val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)
  val image = InputImage.fromBitmap(bitmap!!, 0)
  var outputText = ""
  labeler.process(image)
    .addOnSuccessListener { labels ->
      // Task completed successfully
      for (label in labels) {
        val text = label.text
        val confidence = label.confidence
        outputText += "$text : $confidence\n"
      }
      txtOutput.text = outputText
  }
    .addOnFailureListener { e ->
      // Task failed with an exception
  }
}
  • هنگامی که کاربر برای اولین بار روی دکمه کلیک می کند، کد با استفاده از ImageLabeling.getClient یک برچسب را نشان می دهد و آن را ImageLabelerOptions ارسال می کند. این ویژگی با ویژگی DEFAULT_OPTIONS ارائه می‌شود که به ما امکان می‌دهد سریع راه‌اندازی کنیم.
  • بعد، یک InputImage از بیت مپ با استفاده از روش fromBitmap آن ایجاد می شود. InputImage فرمت مورد نظر ML Kit برای پردازش تصاویر است.
  • در نهایت، برچسب‌گذار تصویر را پردازش می‌کند و یک تماس ناهمزمان، چه در صورت موفقیت و چه در صورت شکست، ارائه می‌کند. اگر استنباط موفقیت آمیز باشد، پاسخ تماس شامل لیستی از برچسب ها خواهد بود. سپس می توانید این لیست برچسب ها را برای خواندن متن برچسب و مقدار اطمینان تجزیه و تحلیل کنید. اگر شکست بخورد، یک استثنا برای شما ارسال می کند که می توانید از آن برای گزارش به کاربر استفاده کنید.

و بس! اکنون می‌توانید برنامه را بر روی دستگاه اندرویدی یا در شبیه‌ساز اجرا کنید. اگر قبلاً هرگز این کار را انجام نداده‌اید، می‌توانید از اینجا یاد بگیرید: https://developer.android.com/studio/run/emulator

در اینجا برنامه در حال اجرا در شبیه ساز است. ابتدا تصویر و دکمه را می بینید و برچسب خالی می شود.

c07f5f307f070dc7.png

دکمه را فشار دهید، مجموعه ای از برچسب ها برای تصویر دریافت خواهید کرد.

550ccaa783363551.png

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

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

در مراحل زیر، نحوه ساخت همین برنامه در iOS را بررسی خواهید کرد.

7. ایجاد یک طبقه بندی تصویر در iOS - شروع کنید

می توانید با استفاده از Xcode یک برنامه مشابه در iOS ایجاد کنید.

  1. Xcode را اجرا کنید و از منوی فایل، New Project را انتخاب کنید. این گفتگو را خواهید دید:

8fb0e6a9d6ac275e.png

  1. همانطور که نشان داده شده برنامه را انتخاب کنید و روی Next کلیک کنید. از شما خواسته می شود که گزینه هایی را برای پروژه خود انتخاب کنید. همانطور که نشان داده شده است یک نام و یک شناسه سازمان به آن بدهید. مطمئن شوید که نوع رابط Storyboard و زبان Swift مطابق شکل است.

76c6bdb5aee7659c.png

  1. اگر می‌خواهید روی یک تلفن مستقر شوید و یک نمایه توسعه‌دهنده تنظیم کنید، می‌توانید تنظیمات تیم خود را تنظیم کنید. اگر نه، آن را در None بگذارید و می توانید از شبیه ساز iOS برای اجرای برنامه خود استفاده کنید.
  2. روی Next کلیک کنید و پوشه ای را برای ذخیره پروژه و فایل های آن انتخاب کنید. مکان این پروژه را به خاطر بسپارید، در مرحله بعد به آن نیاز خواهید داشت.
  3. فعلاً Xcode را ببندید، زیرا پس از مرحله بعدی آن را با استفاده از یک فایل فضای کاری متفاوت دوباره باز می‌کنید.

8. کیت ML را با استفاده از Cocoapods یکپارچه کنید

همانطور که ML Kit روی iOS نیز کار می کند، می توانید از آن به روشی بسیار مشابه برای ساختن یک طبقه بندی کننده تصویر استفاده کنید. برای ادغام آن از CocoaPods استفاده خواهید کرد. اگر قبلاً این را نصب نکرده‌اید، می‌توانید با دستورالعمل‌های موجود در https://cocoapods.org/ این کار را انجام دهید.

  1. دایرکتوری را که در آن پروژه خود را ایجاد کرده اید باز کنید. باید حاوی فایل xcodeproj. شما باشد.

در اینجا می توانید فایل .xcodeproj را ببینید که نشان می دهد من در مکان صحیح هستم.

e2966a47e84eb398.png

  1. در این پوشه یک فایل جدید به نام Podfile ایجاد کنید. هیچ پسوندی وجود ندارد، فقط Podfile است. در داخل آن موارد زیر را اضافه کنید:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. آن را ذخیره کنید و به ترمینال برگردید. در همان دایرکتوری، pod install تایپ کنید. Cocoapods کتابخانه ها و وابستگی های مناسب را دانلود می کند و یک فضای کاری جدید ایجاد می کند که پروژه شما را با وابستگی های خارجی آن ترکیب می کند.

3b4c628b0cbface8.png

توجه داشته باشید که در پایان از شما می خواهد که جلسات Xcode خود را ببندید و از این پس از فایل فضای کاری استفاده کنید. این فایل را باز کنید و Xcode با پروژه اصلی شما به اضافه وابستگی های خارجی راه اندازی می شود.

32090e0024b6b5ef.png

اکنون برای رفتن به مرحله بعدی و ایجاد رابط کاربری آماده هستید.

9. رابط کاربری iOS را با استفاده از Storyboards ایجاد کنید

  1. فایل Main.storyboard را باز کنید، یک طرح رابط کاربری با یک سطح طراحی برای یک گوشی خواهید دید.
  2. در سمت راست بالای صفحه یک دکمه + وجود دارد که می‌توانید از آن برای اضافه کردن کنترل‌ها استفاده کنید. برای دریافت پالت کنترل ها روی آن کلیک کنید.

e63bc3bafa54cc21.png

  1. از آنجا، یک ImageView ، یک دکمه و یک برچسب را روی سطح طراحی بکشید و رها کنید. آنها را مطابق شکل از بالا به پایین مرتب کنید:

f9dfc55616b25f11.png

  1. روی دکمه دوبار کلیک کنید تا متن آن را از Button به Classify ویرایش کنید.
  2. دستگیره های کنترل را در اطراف برچسب بکشید تا بزرگتر شود. (حدود عرض UIImageView و دو برابر ارتفاع را بگویید.)
  3. در حالی که برچسب هنوز انتخاب شده است، روی دکمه انتخابگرها در بالا سمت راست کلیک کنید تا پالت بازرسان نشان داده شود.
  4. پس از انجام این کار، تنظیمات خطوط را پیدا کنید و مطمئن شوید که روی 0 تنظیم شده است. این به برچسب اجازه می دهد تا تعداد خطوط پویا را ارائه دهد.

a39708b320b56b30.png

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

10. Actions و Outlets ایجاد کنید

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

در مرحله بعدی باید خروجی هایی برای ImageView و Label ایجاد کنید. ImageView در کد برای بارگذاری تصویر در آن ارجاع خواهد شد. برچسب در کد ارجاع داده می‌شود تا متن خود را بر اساس استنتاجی که از کیت ML برمی‌گرداند تنظیم کند.

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

77255f7d6284750.png

  1. شما یک طرح بندی صفحه گیج کننده خواهید داشت که در آن main.storyboard دو بار باز می شود. در سمت چپ، در مسیریابی پروژه، ViewController.swift را انتخاب کنید تا کد view controller باز شود. ممکن است به نظر برسد که سطح طراحی شما از ویرایشگر استوری بورد سمت چپ ناپدید شده است، اما نگران نباشید، هنوز آنجاست!
  2. برای بازگرداندن آن، روی View Controller در View Controller Scene کلیک کنید. سعی کنید رابط کاربری خود را به این شکل در آورید - با استوری بورد در سمت چپ که طرح شما را نشان می دهد و کد ViewController.swift در سمت راست.

7eb21c7f9d43c9bc.png

  1. UIImageView را از سطح طراحی در سمت چپ انتخاب کنید و در حالی که کلید CONTROL را فشار می دهید، آن را به سمت کد سمت راست بکشید و آن را درست زیر کلمه کلیدی class رها کنید (در خط 11 در تصویر بالا).

در حین کشیدن یک فلش می بینید و وقتی رها می کنید پنجره ای مانند این ظاهر می شود:

37477f0611948318.png

  1. فیلد نام را به عنوان "imageView" پر کنید و روی اتصال کلیک کنید.
  2. این فرآیند را با برچسب تکرار کنید و نام "lblOutput" را به آن بدهید.
  3. مهم: برای دکمه، همین کار را انجام می دهید، اما مطمئن شوید که نوع اتصال را روی Action تنظیم کرده اید و نه Outlet !

7281b6eea9fb6c23.png

  1. نام آن را «doClassification» بگذارید و روی Connect کلیک کنید.

وقتی کارتان تمام شد، کد شما باید به این شکل باشد: (توجه داشته باشید که نمای برچسب و تصویر به عنوان IBOutlet (خروجی ساز رابط) و دکمه به عنوان IBAction (عمل سازنده رابط) اعلام شده است.)

import UIKit

class ViewController: UIViewController {

    @IBAction func doClassification(_ sender: Any) {
    }
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var lblOutput: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

}
  1. در نهایت، یک تصویر را با برنامه همراه کنید تا بتوانیم طبقه بندی را به راحتی انجام دهیم. برای انجام این کار، فایل را از اکسپلورر فایل خود به کاوشگر سمت چپ Xcode بکشید. وقتی آن را رها کردید، یک پنجره بازشو مانند زیر خواهید داشت:

889ff33eaec785ec.png

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

فایل با برنامه شما همراه می شود و اکنون می توانید به راحتی آن را طبقه بندی کنید. اکنون آماده کدنویسی رابط کاربری برای انجام طبقه بندی تصاویر هستید!

11. کد طبقه بندی تصاویر را بنویسید

اکنون که همه چیز تنظیم شده است، نوشتن کد برای انجام طبقه بندی تصویر واقعاً ساده است.

  1. با بستن طراح داستان با کلیک بر روی X در گوشه سمت چپ بالای سطح طراحی شروع کنید. این به شما امکان می دهد فقط روی کد خود تمرکز کنید. شما ViewController.swift را برای بقیه این آزمایشگاه ویرایش خواهید کرد.
  2. کتابخانه های MLKitVision و MLKit ImageLabeling را با افزودن این کد در بالا، درست در زیر وارد کردن UIKit وارد کنید:
import MLKitVision
import MLKitImageLabeling
  1. سپس، در تابع viewDidLoad خود، ImageView را با استفاده از فایلی که در برنامه قرار داده ایم، مقداردهی اولیه کنید:
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    imageView.image = UIImage(named:"flower1.jpg")
}
  1. یک تابع کمکی برای دریافت برچسب های تصویر، بلافاصله در زیر viewDidLoad() ایجاد کنید:
func getLabels(with image: UIImage){
  1. یک VisionImage از تصویر ایجاد کنید. کیت ML از این نوع در هنگام انجام طبقه بندی تصاویر استفاده می کند. بنابراین، در تابع getLabels، این کد را اضافه کنید:
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
  1. سپس گزینه هایی را برای برچسب تصویر ایجاد کنید. با استفاده از این گزینه ها مقداردهی اولیه می شود. در این مورد، شما فقط یک گزینه اساسی از confidenceThreshold را تنظیم خواهید کرد. این بدان معناست که شما فقط از برچسب‌گذار می‌خواهید برچسب‌هایی را که اطمینان 0.4 یا بالاتر دارند را برگرداند. به عنوان مثال، برای گل ما، کلاس هایی مانند "گیاه" یا "گلبرگ" اعتماد به نفس بالایی دارند، اما کلاس هایی مانند "بسکتبال" یا "ماشین" اعتماد به نفس پایینی خواهند داشت.
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
  1. اکنون برچسب را با استفاده از این گزینه ها ایجاد کنید:
let labeler = ImageLabeler.imageLabeler(options: options)
  1. هنگامی که برچسب را دارید، می توانید آن را پردازش کنید. به شما یک فراخوان ناهمزمان با برچسب‌ها (در صورت موفقیت) و خطا (در صورت عدم موفقیت) می‌دهد، که سپس می‌توانید در یک تابع دیگر که ما در یک لحظه ایجاد می‌کنیم پردازش کنید.
labeler.process(visionImage) { labels, error in
    self.processResult(from: labels, error: error)
  }

اگر Xcode شکایت کرد که هیچ عضو processResult وجود ندارد، نگران نباشید. شما هنوز آن را اجرا نکرده اید، و در مرحله بعد این کار را انجام خواهید داد.

برای راحتی کار، عملکرد کامل getLabels در اینجا آمده است:

// This is called when the user presses the button
func getLabels(with image: UIImage){
    // Get the image from the UI Image element and set its orientation
    let visionImage = VisionImage(image: image)
    visionImage.orientation = image.imageOrientation

    // Create Image Labeler options, and set the threshold to 0.4
    // so we will ignore all classes with a probability of 0.4 or less
    let options = ImageLabelerOptions()
    options.confidenceThreshold = 0.4

    // Initialize the labeler with these options
    let labeler = ImageLabeler.imageLabeler(options: options)

    // And then process the image, with the callback going to self.processresult
    labeler.process(visionImage) { labels, error in
        self.processResult(from: labels, error: error)
 }
}

بنابراین اکنون باید تابع processResult را پیاده سازی کنید. با توجه به اینکه برچسب‌هایی داریم و یک شی خطا به ما بازگردانده شده است، اکنون بسیار ساده است. برچسب ها باید از کیت ML به نوع ImageLabel ریخته شوند.

هنگامی که این کار انجام شد، می‌توانید فقط در میان مجموعه برچسب‌ها تکرار کنید، توضیحات و مقدار اطمینان را بکشید و آنها را به labeltexts var کنید. هنگامی که همه آنها را تکرار کردید، به سادگی lblOutput.text را روی آن مقدار تنظیم می کنید.

این تابع کامل است:

// This gets called by the labeler's callback
func processResult(from labels: [ImageLabel]?, error: Error?){
    // String to hold the labels
    var labeltexts = ""
    // Check that we have valid labels first
    guard let labels = labels else{
        return
    }
  // ...and if we do we can iterate through the set to get the description and confidence
    for label in labels{
        let labelText = label.text + " : " + label.confidence.description + "\n"
        labeltexts += labelText
    }
    // And when we're done we can update the UI with the list of labels
    lblOutput.text = labeltexts
}

تنها چیزی که باقی می ماند این است که وقتی کاربر دکمه را فشار می دهد، getLabels را فراخوانی می کند.

وقتی اکشن را ایجاد کردید همه چیز برای شما سیم‌کشی شد، بنابراین فقط باید IBAction به نام doClassificaiton را که قبلا ایجاد کرده‌اید برای فراخوانی getLabels کنید.

در اینجا کدی برای فراخوانی آن با محتوای imageView آمده است:

@IBAction func doClassification(_ sender: Any) {
    getLabels(with: imageView.image!)
}

اکنون برنامه خود را اجرا کنید و آن را امتحان کنید. شما می توانید آن را در عمل در اینجا ببینید:

eb8e6c1b2e2c65e0.png

توجه داشته باشید که طرح بندی شما ممکن است بسته به دستگاه شما متفاوت به نظر برسد.

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

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

12. تبریک می گویم!

شما اکنون اپلیکیشنی را هم در اندروید و هم در iOS پیاده سازی کرده اید که بینایی اولیه کامپیوتر را با یک مدل عمومی به شما می دهد. شما بیشتر کارهای سنگین را قبلا انجام داده اید.

در Codelab بعدی، یک مدل سفارشی می سازید که انواع گل ها را تشخیص می دهد و تنها با چند خط کد می توانید مدل سفارشی را در این برنامه پیاده سازی کنید تا کاربردی تر شود!