جستجو برای:
  • دوره‌های آموزشی
  • وبلاگ
  • آموزش‌های رایگان
    • آموزش پایتون رایگان
    • آموزش یادگیری ماشین رایگان
    • آموزش یادگیری عمیق رایگان
    • آموزش pytorch رایگان
    • آموزش رایگان matplotlib
    • آموزش گوگل کولب
  • نقشه راه AI
  • کلاس خصوصی
  • همکاری با ما💚
  • حساب کاربری
  • اساتید
  • درباره ما
     
    • 0902-546-9248
    • howsam.mail@gmail.com
    آکادمی هوش مصنوعی هوسم
    • دوره‌های آموزشی
    • آموزش‌های رایگان
      • آموزش پایتون
      • آموزش یادگیری ماشین رایگان
      • آموزش یادگیری عمیق رایگان
      • آموزش pytorch رایگان
      • آموزش گوگل کولب
    • نقشه راه AI
    • وبلاگ
    • درباره ما
      • اساتید
      • پشتیبانی
    0
    ورود / عضویت

    بلاگ

    آکادمی هوش مصنوعی هوسم وبلاگ پردازش تصویر آموزش OpenCV

    آموزش OpenCV

    2023/09/11
    ارسال شده توسط سید سجاد اشرفی
    پردازش تصویر
    10.25k بازدید

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

    فهرست مطالب نمایش
    1. صحبت خودمانی از OpenCV
    2. OpenCV چیست؟
    3. نصب OpenCV در پایتون
    4. فراخوانی و نمایش تصویر در OpenCV
    4.1. فراخوانی تصویر
    4.2. نمایش تصویر
    5. ریسایز تصویر با OpenCV
    6. کراپ (برش) تصویر با OpenCV
    7. چرخش تصویر
    7.1. چرخش تصویر به اندازه دلخواه با OpenCV
    8. رسم شکل هندسی در اوپن سی وی
    8.1. رسم خط روی تصویر
    8.2. رسم دایره روی تصویر
    8.3. رسم مستطیل در OpenCV
    8.4. افزودن متن به تصویر با اوپن سی وی

    صحبت خودمانی از OpenCV

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

    خاطرات زیادی با OpenCV دارم و بخشی از این خاطرات با درد و رنج همراه هست! اولین بار در مقطع ارشد، در درس بینایی کامپیوتر با موجودی به‌نام OpenCV آشنا شدم. تا قبل آن، من و اکثر دوستانم تنها به متلب مسلط بودیم. پایتون هم هنوز بین محققان و دانشجویان شناخته شده نبود. من و دوستانم دانشجوی برق الکترونیک دیجیتال بودیم که می‌خواستیم در حوزه بینایی کامپیوتر کار کنیم و به همین خاطر از دانشکده کامپیوتر درس بینایی کامپیوتر را انتخاب کرده بودیم.

    به استاد گفتیم که ما برقی هستیم و اجازه بده ما تمرین‌ها را با متلب ارائه دهیم، اما قبول نکرد! آن موقع‌ها OpenCV نسخه پایتونی نداشت و باید حتما با ++C کدنویسی می‌زدیم. دو ورژن از OpenCV وجود داشت که یکی خیلی خیلی سخت بود! اما متاسفانه ورژن دیگرش هم خیلی سخت بود! 🙄

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

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

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

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

    OpenCV چیست؟

    OpenCV مخفف عبارت Open Source Computer Vision هست. یعنی یک کتابخانه متن باز در حوزه بینایی کامپیوتر…

    نصب OpenCV در پایتون

    برای نصب OpenCV در پایتون، ابتدا باید cmd را در ویندوز باز کنید. سپس عبارت زیر را در cmd بنویسید:

    pip install opencv-python

    با اجرای کد بالا، کتابخانه OpenCV در پایتون نصب خواهد شد. برای استفاده از کتابخانه OpenCV در پایتون، نصب آن کافی نیست و باید آن را فراخوانی یا import کنیم. برای این کار از دستور import استفاده می‌کنیم:

    import cv2

    با اجرای دستور بالا کتابخانه OpenCV در پایتون فراخوانی خواهد شد. دقت کنید، اسم کتابخانه OpenCV در پایتون cv2 است. با استفاده از دستور زیر می‌توانید ورژن OpenCV را چک کنید:

    print(f'OpenCV version: {cv2.__version__}')
    OpenCV version: 4.5.5

    فراخوانی و نمایش تصویر در OpenCV

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

    فراخوانی تصویر

    با استفاده از دستور imread می‌توانید به راحتی تصاویر با فرمت‌های مختلف مانند JPEG BMP PNG و غیره را فراخوانی کنید. بیایید یک نمونه تصویر فراخوانی کنیم. می‌توانید از اینجا چند نمونه تصویر دانلود و در سیستم خود تست کنید.

    # Load an image from a file
    image = cv2.imread('images/image-2.jpg')

    بیایید با متغیر image که شامل تصویر ماست کمی کار کنیم. جنس این متغیر چیست؟ برای فهمیدن این مساله باید بنویسیم:

    type(image)
    numpy.ndarray

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

    image.shape
    (600, 602, 3)

    می‌دانید منظور از ابعاد چیست؟ همان رزولوشن تصویر که می‌گوییم مثلا این تصویر 2000×3000 هست. در اینجا تصویر ما 602 در 600 هست. 602 سطر و 600 ستون دارد. فعلا به عدد 3 توجه نکنید! بعدا بیشتر درمورد آن توضیح می‌دهم.

    پرینت کردن image هم خالی از لطف نیست!

    print(image)
    array([[[29, 25, 14],
    [29, 25, 14],
    [29, 25, 14],
    ...,
    [29, 25, 14],
    [29, 25, 14],
    [29, 25, 14]]], dtype=uint8)

    مشاهده می‌کنید که انباری از اعداد داریم. هرکدام از این اعداد معادل یک پیکسل در تصویر هستند. البته، نکات مهمی در خروجی بالا مشاهده می‌شود. دیتاتایپ تصویر، unit8 هست؛ یعنی، اعداد درون این آرایه، اعداد صحیح (Integer) بدون علامت (Unsigned) 8 بیتی هستند. بنابراین، اعداد درون این ماتریس باید اعدادی بین 0 تا 255 باشد. نهایتا 256 حالت داریم! اغلب تصاویری که فراخوانی می‌کنیم، چنین ساختاری دارند. یکسری تصاویر خاص مانند تصاویر پزشکی یا تصاویر ماهواره‌ای ممکن هست دیتاتایپ متفاوتی داشته باشند.

    هشدار یکی از اشتباهات رایج در بارگذاری تصویر، مسیر اشتباه از تصویر هست. اگر مسیر اشتباه باشد، OpenCV اصلا به روی خودش نمی‌آورد و هیچ خطایی به شما نشان نمی‌دهد. وقتی آدرس درست نباشد، None را در متغیر مدنظر می‌ریزد! اینطور نیست که بگوید آدرس اشتباه هست. این باعث می‌شود که افراد فکر کنند چون خطایی نداریم، پس تصویر به درستی فراخوانی شده! با کد زیر می‌توانید خروجی تصویر را چک کنید:

    # Load an image from a file
    image = cv2.imread('image-0.jpg')
    
    # Check if the image was loaded successfully
    if image is not None:
        print('Image loaded successfully')
    else:
        print('Failed to load image')

    نمایش تصویر

    برای نمایش تصویر بارگذاری‌شده باید از دستور imshow استفاده کنیم. دستور imshow دو ورودی دریافت می‌کند:

    • عنوان این تصویر هنگام نمایش (نام دلخواه)
    • تصویر (نام متغیری که تصویر در آن ریخته شده!)

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

    # Display the loaded image
    cv2.imshow('Loaded Image', image)
    cv2.waitkey(0)

    و این هم نتیجه 😍:

    نکته 1 اگر در محیطی مانند Pycharm یا VSCode کدنویسی می‌کنید. حتما باید دستور ()cv2.waitkey را بنویسید تا نتیجه را به شما نشان دهد. عددی که داخل پرانتز این دستور نوشته می‌شود، زمان انتظار هست. اگر عدد صفر باشد، پنجره نمایش تصویر به‌صورت دائمی باز خواهد بود. اما اگر مثلا عدد 1000 بنویسید، بعد از 1 ثانیه به‌صورت خودکار بسته می‌شود.

    نکته 2 اگر در محیط‌های نوتبوکی کد را اجرا می‌کنید، بدانید که دستور ()cv2.imshow در این محیط کار نمی‌کند. برای نمایش تصویر از دستور plt.imshow(img) استفاده کنید. ()plt.imshow یکی از دستورات فریمورک matplotlib هست.

    import matplotlib.pyplot as plt
    plt.imshow(image)
    plt.axis('off')

    نکته 3 احتمالا بعد از اجرای دستورهای نکته 2 ‌می‌بینید که تصویر شما آبی است و با تصویری که ما نمایش دادیم متفاوت است. دلیل این کار این است که matplotlib تصاویر را به صورت RGB می‌خواند و پردازش می‌کند، ولی OpenCV تصاویر را به صورت BGR می‌بیند! 🤯😵 بنابراین شما برای اینکه تصویر را با matplotlib نمایش دهید نیاز به یک خط کد دارید که تصویر را از BGR به RGB تبدیل کند:

    import matplotlib.pyplot as plt
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    plt.imshow(image_rgb)
    plt.axis('off')

    نکته 4 باید دقت کنید که در OpenCV شوخی کردم بابا نکته 4 نداریم دیگه 😜

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

    ریسایز تصویر با OpenCV

    ریسایز تصویر یکی از کارهای رایج در کار با تصاویر هست. اتفاقا از جمله کارهایی هست که بسیار از کاربرهای کامپیوتر با آن آشنا هستند و با نرم‌افزارهای ساده مانند Paint هم می‌توان چنین کاری را انجام داد. اما می‌خواهم به زبان علم پردازش تصویر درباره ریسایز صحبت کنم؛ ریسایز تصویر، یعنی تغییر رزولوشن (HxW) تصویر… مثلا، می‌خواهیم یک تصویر به ابعاد 300×300 را به تصویری به ابعاد 100×100 یا به ابعاد 600×600 تبدیل کنیم.

    نکته به ریسایزی که منجر به بزرگ شدن تصویر شود، نمونه‌برداری افزایشی (Up sampling) و به ریسایز منجر به کوچک شدن تصویر، نمونه‌برداری کاهشی (Down sampling) گفته می‌شود.

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

    حالا با این مقدمه، بیایید ببینیم ریسایز تصویر با OpenCV چگونه انجام می‌شود. با استفاده از دستور ()cv2.resize می‌توانیم به راحتی ریسایز انجام دهیم. اما ورودی‌های این دستور:

    • src: تصویر ورودی که می‌خواهیم آن را ریسایز کنیم.
    • dsize: سایزی که می‌خواهیم تصویر را به آن ریسایز کنیم.
    • interpolation: تکنیک درون‌یابی

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

    • INTER_NEAREST: یکی از ساده‌ترین روش‌های درون‌یابی براساس نزدیک‌ترین همسایگی
    • INTER_LINEAR: روش دوخطی (Bilinear) که بازهم ساده و کم‌هزینه هست. گزینه پیش‌فرض هم همین هست.
    • INTER_CUBIC: روش کیوبیک که از دو روش اول بهتر هست، اما هزینه محاسبات بیشتری هم دارد. یعنی زمان‌برتر هست. زمان‌برتر؟! 🤔
    • INTER_LANCZOS4: روش لَنکزوس حتی از روش کیوبیک هم هزینه بیشتری دارد.
    • موارد دیگری هم هست که بگذریم…

    حالا بیایید با یک مثال، نحوه استفاده از این دستور را تمرین کنیم. کد زیر، تصویر ورودی را به ابعاد 250*300 ریسایز می‌کند. مشاهده می‌کنید که من تنها دو ورودی تصویر و سایز را مشخص کرده‌ام و درون‌یابی را تغییر نداده‌ام.

    image_resized = cv2.resize(image, (300, 250))
    image_resized.shape
    (250, 300, 3)

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

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

    تصویر اصلی تصویر ریسایز شده

    تصویر اصلی با ابعاد 602*600

    تصویر ریسایز شده با ابعاد 300*300

    cv2.resize(image0, (300, 300))

    تصویر اصلی با ابعاد 750*938

    تصویر ریسایز شده با ابعاد 100*400

    cv2.resize(image1, (100, 400))

    تصویر اصلی با ابعاد 468*500

    تصویر ریسایز شده با ابعاد 680*700

    cv2.resize(image2, (700, 680))

    اما نکته مهمی که وجود دارد این هست که بعضی از تصاویر از حالت نرمال خود خارج شده‌اند. چرا اینطور شده؟ دلیلش این هست که نسبت ابعاد (Aspect Ratio) را به هم ریخته‌ایم. به سطر دوم از جدول بالا نگاه کنید. نسبت ارتفاع به پهنا در تصویر اصلی ما، 938/750 یعنی 1.25 هست، درحالی‌که این نسبت ارتفاع به پهنا در تصویر ریسایز شده برابر با 4 است. وقتی این نسبت را تغییر دهیم، خروجی ما دِفُرمه می‌شود. همه اینها را در نرم‌افزارها هم می‌توان دید. یک آیکن برای حفظ نسبت ارتفاع به پهنا دارند.

    کراپ (برش) تصویر با OpenCV

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

    برش یا Crop تصویر با OpenCV

    خبر خوب اینکه، برای برش تصویر نیازی به opencv نداریم! شاید کسانی که به نامپای مسلط هستند، می‌دانند که چه می‌گویم. ببینید، ما بالاتر نشان دادیم که وقتی تصویری با opencv خوانده می‌شود، یک آرایه نامپای هست. این یعنی، ما می‌توانیم با استفاده از تکنیک اسلایس در نامپای، به راحتی تصاویر را برش بزنیم. در برش تصویر، ما به بُعد کانال کاری نداریم. پس آن عدد 3 را کنار بگذارید. ما باید محدوده مدنظرمان روی بُعد ارتفاع و پهنای تصویر مشخص کنیم. به‌صورت کلی، فرمول برش تصویر به شکل زیر است:

    cropped_image = image[hs:he, ws:we, :]

    در فرمول بالا، hs و he به‌ترتیب به ابتدا و انتهای بازه برش در ارتفاع اشاره می‌کنند. به‌صورت مشابه، ws و we هم به ابتدای و انتهای بازه پهنا اشاره دارند. حالا بیایید، یک نمونه مثال ببینیم:

    img = cv2.imread('image-1.jpg')
    
    cropped_img = img[110:480, 75:450, :]
    cropped_img2 = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2RGB)
    
    print(f'Original Image: {img.shape}, Cropped Image: {cropped_img.shape}')
    
    plt.imshow(img);
    plt.imshow(cropped_img2);

    این هم خروجی:

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

    این هم از برش تصویر که انصافا ساده بود…

    چرخش تصویر

    یکی دیگر از عملگرهای پایه‌ای در پردازش تصویر، چرخش تصویر به اندازه یک زاویه مشخص هست. خوشبختانه OpenCV برای این چرخش تصویر یک دستور آماده بنام cv2.rotate دارد. همان‌طور که در زیر نشان داده شده، این دستور به دو ورودی نیاز دارد:

    • src: تصویری که می‌خواهیم بچرخانیم.
    • rotateCode: کد چرخش تصویر با سه حالت زیر:
      • cv2.ROTATE_90_CLOCKWISE معادل با 90 درجه چرخش ساعت‌گرد
      • cv2.ROTATE_180 معادل با 180 درجه چرخش
      • cv2.ROTATE_90_COUNTERCLOCKWISE معادل با 90 درجه چرخش پادساعت‌گرد
    rotated_image = cv2.rotate(src, rotateCode)

    احتمالا سوالی که برایتان پیش آمده این هست که نمی‌توانیم مثلا به اندازه دلخواه بچرخانیم؟ مثلا 10 درجه؟ با این دستور نمی‌توانیم. اما در همین بخش راه‌کار چرخش به اندازه دلخواه را هم می‌گویم. حالا یک مثال از چرخش هم ببینیم. با کد زیر یک تصویر با چرخش 90 درجه ساخته‌ایم:

    # Load the input image
    image = cv2.imread('input_image.jpg')
    
    # Rotate the image by 90 degrees clockwise
    rotated_image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
    چرخش تصویر به اندازه 90 درجه؛ (چپ) تصویر اصلی، (راست) تصویر چرخیده

    نکته بدون استفاده از دستور rotate هم می‌توانیم تصویر را به اندازه 90 180 90- بچرخانیم. یک نمونه را من می‌گویم و بقیه موارد را خودتان فکر کنید و راهش را پیدا کنید. با یک ترنسپوز ماتریس به سادگی می‌توانیم تصویر را 90 درجه بچرخانیم.

    چرخش تصویر به اندازه دلخواه با OpenCV

    برای چرخش تصویر به اندازه دلخواه، مثلا 10 یا 20 درجه، باید از دو دستور cv2.getRotationMatrix2D و cv2.warpAffine استفاده کنید. می‌دانم، اسم‌هایشان کمی ترسناک است! اما کار با آنها ساده است. راه‌کار هم این است:

    • ابتدا دستور cv2.getRotationMatrix2D را می‌نویسیم و بعد
    • خروجی دستور بالا را همراه با تصویر اصلی به cv2.warpAffine می‌دهیم.
    • تمام!

    ورودی‌های دستور cv2.getRotationMatrix2D چگونه است؟ سه ورودی دارد:

    • center: مرکز چرخش (همان مرکز تصویر که باید پیدایش کنیم.)
    • angle: همان زاویه مدنظر ما برای چرخش
    • scale: فاکتور مقیاس که می‌تواند تصویر را مقیاس کند (کوچکتر و بزرگتر)
    cv2.getRotationMatrix2D(center, angle, scale)

    خروجی این دستور هم یک ماتریس 2 در 3 هست که ماتریس چرخش نام دارد. این ماتریس چرخش را باید به دستور cv2.warpAffine بدهیم.

    ورودی‌های دستور cv2.warpAffine زیاد است و ما همه آنها را توضیح نمی‌دهیم. تنها چند موردی که نیاز داریم:

    • src: تصویر ورودی
    • M: ماتریس چرخش
    • dst: سایز تصویر خروجی
    • flags: روش درون‌یابی یا Interpolation (همان‌هایی که در ریسایز دیده بودیم.)
    cv2.warpAffine(src, M, dsize, dst, flags, borderMode, borderValue)

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

    • مرکز تصویر را با استفاده از image.shape و تقسیم بدست آوردیم.
    • این مرکز تصویر را همراه با درجه دلخواه و مقیاس 1 به دستور cv2.getRotationMatrix2D دادیم.
    • خروجی cv2.getRotationMatrix2D را rotation_matrix نام‌گذاری کردیم.
    • تصویر اصلی، ماتریس چرخش، سایز تصویر و روش درون‌یابی را به دستور cv2.warpAffine دادیم.
    • خروجی rotated_image هم تصویر چرخیده هست.
    import numpy as np
    
    # Load the input image
    image = cv2.imread('image-0.jpg')
    
    # Define the rotation angle (in degrees)
    angle = 45
    
    # Get the image center and rotation matrix
    height, width = image.shape[:2]
    image_center = (width/2, height/2) 
    rotation_matrix = cv2.getRotationMatrix2D(image_center, angle, 1.0)
    
    # Perform the affine transformation
    rotated_image = cv2.warpAffine(image, rotation_matrix, (width, height), flags=cv2.INTER_LINEAR)
    

    این هم خروجی کد بالا:

    چرخش تصویر به اندازه دلخواه؛ (چپ) تصویر اصلی، (راست) تصویر چرخیده به اندازه 45 درجه

    ممکن است این سوال برایتان ایجاد شود که “آخه چنین چیزی به چه دردی میخوره؟؟” کاربردهای همین عملگر پایه‌ای پردازش تصویر بسیار جالب و زیاد است:

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

    در این تصویر پانوراما یک مجموعه تصاویر کوچکتر در موقعیت درستی کنار هم قرار گرفته‌اند.

    تصویر پانوراما [منبع]
    تا اینجای کار، درباره مطالب زیر صحبت کردیم:
    • خواندن و نمایش تصویر
    • مشاهده خواص تصویر، مانند سایز تصویر، فضای رنگی و غیره
    • دستکاری تصویر مانند ریسایز، برش و چرخش تصویر

    حالا برویم سراغ بخش بعدی آموزش OpenCV که بسیار جالب هست…

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

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

    • رسم خط روی تصویر
    • رسم دایره روی تصویر
    • رسم مستطیل روی تصویر
    • رسم بیضی روی تصویر
    • نوشتن متن روی تصویر

    توجه در بالا کلمه “رسم” را به کار بردم؛ اما مساله این هست که این رسم‌ها با آنچه در متپلات داریم، متفاوت هست. اشکال هندسی به خود تصویر اضافه می‌شوند و اینطور نیست که صرفا در نمایش ظاهر شوند. شاید حرفم کمی مبهم باشد، احتمالا در ادامه این ابهام رفع می‌شود. 

    در ادامه، درمورد تک‌تک کارهای بالا صحبت کرده‌ام.

    رسم خط روی تصویر

    با استفاده از دستور ()cv2.line می‌توانیم به یک تصویر خط اضافه کنیم. سینکتس این دستور به شکل زیر است:

    cv.line(image, p0, p1, color, thickness)

    آرگومان ورودی دستور بالا:

    • image: تصویری که می‌خواهیم به آن خط اضافه شود.
    • p0: نقطه شروع خط (x, y)
    • p1: نقطه پایان (x, y)
    • color: رنگ خط
    • thickness: ضخامت خط

    حالا بیایید یک مثال هم ببینیم؛ در مثال زیر، یک تصویر خالی (تصویر تماما سیاه) ساخته‌ام و بعد روی آن دو خط رسم کرده‌ام:

    RED = (0, 0, 255)
    YELLOW = (0, 255, 255)
    
    p0 = (10, 10)
    p1 = (300, 90)
    p2 = (400, 10)
    
    img = np.zeros((100, 500, 3), np.uint8)
    cv2.line(img, p0, p1, RED, 2)
    cv2.line(img, p1, p2, YELLOW, 5)
    
    cv2_imshow(img)

    اما شرح کد بالا:

    • اول دو متغیر RED و YELLOW برای رنگ خط‌ها تعیین کرده‌ایم. براساس همان BGR که قبلا گفتیم.
    • سه نقطه p2 p1 p0 برای آغاز و پایان خطوط ساخته‌ایم. نقطه‌ها باید به‌صورت دوبعدی تعریف شوند.
    • یک تصویر تماما سیاه ساخته‌ایم. خیلی ساده با یک دستور نامپای…
    • اولین خط: از p0 تا p1 با رنگ قرمز و پهنای خط 2
    • دومین خط: از p1 تا p2 با رنگ زرد و پهنای خط 5

    بدون اینکه شکل را ببینیم، می‌توانیم حدس بزنیم که دو خط در یک نقطه (p1) مشترک هستند. همچنین، خط زرد ضخامت بیشتری نسبت به خط قرمز دارد. و اما خروجی:

    رسم خط با اوپن سی وی

    رسم دایره روی تصویر

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

    cv2.circle(image, center_coordinates, radius, color, thickness)

    نمی‌خواهم درمورد آرگومان‌های ورودی دستور توضیح دهم. چون بسیار ساده و واضح هست. یک مثال ببینیم:

    BLUE = (255, 0, 0)
    
    c0 = (250, 50)
    
    img = np.full((100, 500, 3), 255, np.uint8)
    
    cv2.circle(img, c0, 10, BLUE, 2)
    cv2.circle(img, c0, 20, BLUE, 2)
    cv2.circle(img, c0, 30, BLUE, 2)
    cv2.circle(img, c0, 40, BLUE, 2)
    cv2.circle(img, c0, 50, BLUE, 2)
    cv2.circle(img, c0, 60, BLUE, 2)
    
    cv2_imshow(img)

    این هم خروجی جالب کد بالا:

    رسم دایره با OpenCV

    رسم مستطیل در OpenCV

    دیگر تکراری شده! چون دستورات رسم اشکال بسیار ساده و شبیه هم هستند. برای رسم یک مستطیل باید از دستور با ورودی‌های زیر استفاده کنیم:

    cv2.rectangle(image, p0, p1, color, thickness)

    ورودی‌ها را باهم مرور کنیم:

    • image: تصویر ورودی که می‌خواهیم روی آن مستطیل بکشیم.
    • p0: مختصات گوشه بالا-چپ مستطیل (x, y)
    • p1: مختصات گوشه پایین-راست مستطیل (x, y)
    • color: رنگ مرز (Border) مستطیل
    • thickness: ضخامت مرز مستطیل

    در کد زیر، یک مستطیل دور چهره شخص موجود در تصویر رسم شده است:

    CYAN = (255, 255, 0)
    
    p0 = (25, 50)
    p1 = (140, 200)
    
    img = cv2.imread('/content/images/image-3.jpg')
    cv2.rectangle(img, p0, p1, CYAN, 2)
    
    cv2_imshow(img)

    این هم نتیجه کار:

    رسم مستطیل روی چهره با استفاده از OpenCV

    نکته شاید بخواهید مستطیل توپر رسم کنید. برای این کار باید آرگومان thickness را برابر با 1- یا cv.FILLED قرار دهید. در چنین شرایطی، رنگ درج‌شده در آرگومان color برای رنگ‌آمیزی کل مستطیل استفاده خواهد شد. 

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

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

    اگر دوست دارید یولو را هم یاد بگیرید، لینک روبرو را مطالعه کنید: آموزش یولو 8

    حالا برویم سراغ یک مورد جذاب و کاربردی دیگر!

    افزودن متن به تصویر با اوپن سی وی

    ادامه دارد…

    اشتراک گذاری:

    مطالب زیر را حتما مطالعه کنید

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

    13 دیدگاه

    به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.

    • امیرعلی ت گفت:
      2026/05/16 در 4:05 ب.ظ

      دقیقا از کجا باید شروع کنیم آدرس فایلمون رو داد

      پاسخ
      • هوسم گفت:
        2026/05/16 در 4:53 ب.ظ

        معمولا با دستور cv2.imread شروع میکنیم. به این دستور، آدرس یک تصویر رو میدید تا بخونه. اوایل همین پست آموزش OpenCV این رو گفتیم. یک فایل پایتونی (مثلا test.py) درست کنید و توی یک پوشه بذارید. توی همون پوشه یک تصویر هم بذارید (مثلا sample.jpg). بعدش با صرفا نوشتن اسم فایل، تصویر خونده میشه:
        cv2.imread(‘sample.jpg’)

        پاسخ
    • saalek110 گفت:
      2026/04/25 در 1:00 ق.ظ

      آموزش مفید و خوبی بود.

      پاسخ
    • کوروش گفت:
      2026/01/03 در 11:02 ب.ظ

      اقا دمتون گرم خدایی سایت خیلی خوبی هستید خداحفظتون کنه❤

      پاسخ
      • هوسم گفت:
        2026/02/04 در 12:03 ق.ظ

        نظر شما باعث خوشحالی و افتخار ماست. ممنون 😊🙏

        پاسخ
    • Hrenani گفت:
      2024/12/20 در 11:26 ق.ظ

      عالی و بینظیر مثل همیشه، لطفا ادامه را هم قرار دهید خیلی کاربردی بود

      پاسخ
      • هوسم گفت:
        2024/12/21 در 9:45 ق.ظ

        ممنون 🙏🌹
        بله، ادامه میدیم.

        پاسخ
    • حمید گفت:
      2024/08/26 در 12:20 ب.ظ

      بسیار بسیار عالی ، روان ، ساده و کاربردی.
      فوق العاده بود. لذت بردم

      پاسخ
      • هوسم گفت:
        2024/08/26 در 3:02 ب.ظ

        ممنون 😊🙏
        موفق باشید 🌹

        پاسخ
    • سارا گفت:
      2024/02/14 در 12:36 ق.ظ

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

      پاسخ
      • هوسم گفت:
        2024/07/08 در 11:55 ق.ظ

        سپاس 😊🌹

        پاسخ
        • امیرعلی گفت:
          2025/08/09 در 9:21 ب.ظ

          ممنون ولی خیلی سخت بود😵‍💫

          پاسخ
          • هوسم گفت:
            2025/08/15 در 11:51 ق.ظ

            پیشنهاد ما این هست که چند بار بخونید، کدها رو خودتون بنویسید و تمرین کنید.

            پاسخ

    دیدگاهتان را بنویسید لغو پاسخ

    جستجو برای:
    دوره‌های جامع هوسم
    • مسابقه Kaggle: تحلیل و پیش‌بینی رفتار با داده‌های چندحسگری سری زمانی
    • پیاده‌سازی ChatGPT از صفر با پایتورچ
    • آموزش OpenCV: از پردازش تا بینایی
    • دیپ کاتالیست: دوره افزایش مهارت
    • پایتون برای هوش مصنوعی 🤖
    • یادگیری ماشین جامع: از مفاهیم تا پیاده‌سازی🔥
    • یادگیری عمیق جامع: از مفاهیم تا پیاده‌سازی
    درباره هوسم

    آکادمی هوش مصنوعی هوسم با آموزش‌های تخصصی در حوزه هوش مصنوعی در خدمت شماست. روی کمک هوسم حساب کنید…

    • گیلان- شهرستان رودسر- شهرک انصاری- کوچه لاله 9
    • 09025469248
    • howsam.mail@gmail.com
    دسترسی سریع
    • صفحه اصلی
    • وبلاگ
    • حساب کاربری
    • سبد خرید
    شبکه‌های اجتماعی

     

    logo-samandehi
    تمامی حقوق برای آکادمی هوسم محفوظ است.
      کد تخفیف شما هست و فقط
      فرصت داری ازش استفاده کنی!
      کد تخفیف شما هست و فقط
      فرصت داری ازش استفاده کنی!
      کد تخفیف شما هست و فقط
      فرصت داری ازش استفاده کنی!
      کد تخفیف شما هست و فقط
      فرصت داری ازش استفاده کنی!
      کد تخفیف شما هست و فقط
      فرصت داری ازش استفاده کنی!
      ورود
      استفاده از موبایل
      استفاده از آدرس ایمیل
      آیا هنوز عضو نیستید؟ اکنون عضو شوید
      بازنشانی رمز عبور
      استفاده از موبایل
      استفاده از آدرس ایمیل
      عضویت
      استفاده از موبایل
      استفاده از ایمیل
      قبلا عضو شدید؟ اکنون وارد شوید

      ورود

      رمز عبور را فراموش کرده اید؟

      هنوز عضو نشده اید؟ عضویت در سایت