Mohsen Khoshnazar Homepage

Mohsen Khoshnazar Homepage
سلام به همه.
سعی می کنم تجربیات خودم رو در این وبلاگ قرار بدم تا دیگر علاقه مندان نیز بتوانند از آنها استفاده کنند.
موفق باشید:)

Telegram Channel: mohsenteq
Instagram: mohsenteq
Site: www.mteq.ir
دنبال کنندگان ۱ نفر
این وبلاگ را دنبال کنید
آخرین نظرات
پنجشنبه, ۲۰ خرداد ۱۳۹۵، ۰۲:۲۹ ب.ظ

تشخیص اشکال چند ضلعی

سلام.

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

   هدف از این پست آشنایی با تشخیص لبه، پیدا کردن محیط ها (Contours)، پیدا کردن مختصات گوشه های یک شکل هندسی، فیلتر کردن و... . شاید این سوال برای افرادی که در ابتدای راه هستند پیش بیاید که چگونه متوجه شویم باید از چه توابع و الگوریتم هایی استفاده کنیم؟ خب به مرور زمان و تمرین، با بیشتر توابع آشنا خواهید شد ولی در مورد روند کار، همیشه سعی کنید مراحل الگوریتم خود را از آخر به اول بر روی کاغذ بنویسید. به عنوان مثال برای تشخیص اشکال هندسی، الگوریتم را از آخر به اول به صورت زیر در نظر می گیرم:

  1. هدف تشخیص چند ضلعی است

  2. محاسبه تعداد رئوس هر شکل (تعداد رئوس با تعداد ضلع ها در اشکال منتظم برابر است)

  3. برای محاسبه تعداد رئوس، باید برای هر شکل یک چند ضلعی با دقت بالا تخمین بزنیم

  4. برای تخمین چند ضلعی باید محیط های بسته(Contours) را پیدا کنیم

  5. برای پیدا کردن محیط های بسته باید لبه ها را پیدا کنیم

  6. برای پیدا کردن لبه ها لازم است تصویر اصلی از حالت رنگی به سیاه و سفید تبدیل شود (و در صورت نیاز فیلتر شود برای حذف نویز های فرکانس بالا)

  7. فراخوانی پکیج های مورد نیاز

   خب روند کدنویسی در بالا آمده است. حال کافیست از پایین (مرحله 7) به بالا (مرحله 1) کدنویسی را شروع کنیم. خب حرف زدن کافیه بریم سراغ کد.

# import the necessary packages
import cv2

# load the image
image=cv2.imread("shapes.PNG")

   در ابتدا پکیج cv2 را برای OpenCV فراخوانی می کنیم. سپس تصویر مورد نظر را بارگذاری می نماییم. شکل زیر تصویری است که می خواهیم اشکال هندسی درون آن را شناسایی کنیم.

# convert the image to grayscale, blur it and find edges
# in the images
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
gray=cv2.GaussianBlur(gray,(5,5),0)
edged=cv2.Canny(gray,75,100)

   برای این که بتوانیم لبه ها را تشخیص دهیم لازم است تصویر از حالت رنگی به سیاه و سفید تبدیل شود. برای این منظور با استفاده از دستور cv2.cvtColor حالت تصویر را از BGR به GRAY تبدیل می کنیم.

   سپس برای تشخیص بهتر لبه ها تصویر سیاه و سفید را فیلتر می نمایید. فیلتر گاوسی برای این منظور مناسب است (البته اگر فیلتر دیگری مد نظرات است می توانید از آن استفاده کنید).

   و در آخر دستور cv2.Canny لبه های موجود در تصویر را پیدا می کند. شکل زیر لبه های پیدا شده را نشان می دهد.

# find contours in the edged image
(_,contours,_)=cv2.findContours(edged,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

   اکنون تمامی محیط های بسته درون تصویر بالا را با استفاده از دستور cv2.findContours پیدا خواهیم کرد.

# loop over the contours
for c in contours:
    # approximate the contours
    peri=cv2.arcLength(c,True)
    approx=cv2.approxPolyDP(c,0.009*peri,True)

    #if our approximated contour has three, four or five points, then we
    # can assume thet we have found triangle, quadrate and pentagon
    if len(approx)==3:
        cv2.drawContours(image,[approx],-1,(0,255,0),2)
    elif len(approx)==4:
        cv2.drawContours(image,[approx],-1,(255,0,0),2)
    elif len(approx)==5:
        cv2.drawContours(image,[approx],-1,(0,0,255),2)
    else:
        cv2.drawContours(image,[approx],-1,(0,0,0),2)

   در این مرحله برای تمامی کانتورهایی که در مرحله قبلی پیدا کردیم (درون متغیر contours ذخیره شده اند) یک چند ضلعی با دقت بسیار بالا (0.009*peri) تخمین می زنیم. دستور cv2.approxPolyDP همانطور که از نامش پیداست، برحسب شکل کانتور (متغیر c) یک چند ضلعی با دقتی که ما تعیید کرده ایم تخمین می زند و خروجی آن مختصات رئوس این چند ضلعی خواهد بود (متغیر approx دارای مختصات رئوس چند ضلعی تخمینی است)

   اکنون تنها لازم است تعداد المان های درون متغیر approx را بررسی کنیم تا بتوانیم اشکال سه ضلعی، چهار ضلعی و پنج ضلعی را پیدا کنیم. اشکال سه ضلهی را با رنگ سبز، چهار ضلعی را با رنگ آبی، اشکال پنج ضلعی را به رنگ قرمز و باقی اشکال را به رنگ سیاه نشان می دهیم.

# show and save Results
cv2.imshow("image",image)
cv2.imwrite("Result.jpg",image)
cv2.imwrite("Edged.jpg",edged)
cv2.waitKey(0)
cv2.destroyAllWindows()

   در پایان نیز نتایج را نشان داده و در صورت لزوم آنها را ذخیره می کنیم. شکل زیر نتیجه نهایی را نشان خواهد داد.

   خب به همین سادگی اشکال را پیدا کردیم. برای تمرین بیشتر سعی کنید شماره هر مرحله را مشخص کنید تا بهتر الگوریتم و کد را درک کنید. در پایان می توانید کد و تصاویر را دانلود نمایید.

دریافت

حجم: 88.6 کیلوبایت

توضیحات: Polygon Detection


نظرات (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی