مروزه با کمک پردازش تصویر و هوش مصنوعی میتوان تحلیلهای عمیقی انجام داد. تشخیص چهره، تشخیص چشم، تشخیص خودرو و … از این دسته از تحلیلها میباشند. اما پردازش تصویر چگونه انجام میگیرد یا چگونه میتوان آن را پیاده سازی کرد. امروز در همین خصوص، وارد مبحث آستانه گذاری OTSU در OpenCV خواهیم شد.
ماژول opencv
Opencv یکی از ماژولهای پردازش تصویر و هوش مصنوعی میباشد. با کمک این ماژول میتوان تصاویر را دریافت و بسیاری از عملیاتهای پردازش تصویر را پیاده سازی کرد. جالب است بدانید با opencv میتوان تشخیص چهره، تشخیص چشم و یا حتی تشخیص اعداد را نیز انجام داد. علاوه بر تصاویر، پردازش ویدئو نیز میتوان با کمک این ماژول انجام داد. در این مقاله، آستانهگذاری تصاویر را با کمک OPENCV و زبان برنامهنویسی پایتون پیادهسازی خواهیم کرد. البته بعضی از قسمتها به موجب نیاز، از ماژول Numpy نیز استفاده میگردد. Pdf آموزش Numpy از این لینک میتوانید تهیه نمایید.
آستانه گذاری تصویر چیست
آستانه گذاری تصویر یکی از سادهترین روشهای ناحیهبندی تصویر است که در آن مقدار پیکسلهای یک تصویر با توجه به آستانه تعیین شده، به صفر یا مقدار ماکزیمم (255 یا 1) تغییر پیدا میکنند. در آستانهگذاری، تصویر دارای دو ناحیه میباشد . (پیکسلهای بزرگتر از آستانه و کوچکتر از آن).
در این آموزش با کمک ماژول opencv در پایتون به پیاده سازی آستانهگذاری خواهیم پرداخت. در آموزش گذشته چندین روش آستانهگذاری را یاد گرفتیم. ابتدا مروری بر روشهای جلسه گذشته میکنیم:
- cv2.THRESH_BINARY: اگر مقدار پیکسل بیشتر از آستانه باشد، مقدار آن 255 و در غیر اینصورت به 0(سیاه رنگ) تغییر میکند.
- cv2.THRESH_BINARY_INV: معکوس روش بالا می باشد.
- THRESH_TRUNC: اگر مقدار پیکسل بیشتر از آستانه باشد، مقدار آن برابر با آستانه و در غیر اینصورت مقدار آن تغییری پیدا نخواهد کرد.
- cv.THRESH_TOZERO: تمامی پیکسلهای کمتر از آستانه برابر با صفر میشوند.
- cv.THRESH_TOZERO_INV: معکوس روش قبل است.
تمامی روشهای بالا مقدار آستانه توسط ما (به صورت دستی) وارد میشد. آیا روشی وجود ندارد که به صورت اتوماتیک مقدار آستانه را بدست بیاورد و در تصویر اعمال کند؟ بله وجود دارد و آن روش Otsu است.
آستانه گذاری OTSU در OpenCV
روش OTSU مقدار آستانه یک تصویر را بدست میآورد. اما چگونه؟ در این مقاله وارد مبحث ریاضی و اثبات این روش نخواهیم شد. اما توضیح کوتاهی در این زمینه خواهیم داد. روش Otsu دو فرض اولیه دارد:
- تصویر شامل دو نوع پیکسل میشود یکی Background و دیگری Forground.
- هیستوگرام Grayscale تصویر به صورت bi-modal است. یعنی هیستوگرام شامل دو peak میباشد.

در تصویر بالا یک عکس به همراه هیستوگرام آن نمایش داده شده است. همانطور که در هیستوگرام مشاهده میکنید دارای دو peak میباشد. peak اول که حالت نوک تیز دارد را background و peak دوم که حالت ملایمتری دارد را foreground میگویند. روش OTSU مقدار آستانه را طوری تعیین میکند که میزان واریانس بین background و foreground حداقل باشد.
آمادهسازی تصویر
ما قبل از هر اقدامی نیاز است ماژولهای مورد نیاز را فراخوانی نماییم:
import cv2
import numpy as np
در این قسمت تصویر ورودی را ابتدا میخوانیم:
image = cv2.imread('codegate.jpg',0)
cv2.imshow("Original", image)
تصویر ورودی به صورت زیر میباشد:

تصویر ورودی لوگو وبسایت کدگیت میباشد. این تصویر به صورت grayscale است.
پیاده سازی آستانه گذاری OTSU
برای آستانه گذاری به روش OTSU، ماژول OpenCV تابع threshold را پیادهسازی کرده است. این تابع را در آموزش گذشته معرفی کردیم. مجدداً ورودیهای تابع threshold را مرور نماییم:
- تصویر ورودی (باید grayscale باشد)
- مقدار آستانه یا thresholdValue
- مقدار ماکزیمم پیکسل یا maxVal
- روش آستانهگذاری یا thresholdingTechnique
اکنون میخواهیم روش THRESH_BINARY را پیادهسازی کنیم. کد زیر را ببینید:
(T, threshInv) = cv2.threshold(image, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
cv2.imshow("threshInv with OTSU", threshInv)
در کد بالا تابع threshold را با ورودیهای زیر صدا زدهایم:
- image (تصویر ورودی)
- عدد 0 (مقدار آستانه): با توجه به اینکه ما میخواهیم از روش OTSU استفاده کنیم و مقدار آستانه توسط این روش بدست بیاید. پس عملاً عدد صفر به معنی در نظر نگرفتن این ورودی میباشد.
- عدد 255 (مقدار ماکزیمم پیکسل)
- cv2.THRESH_BINARY و cv2.THRESH_OTSU (روش آستانهگذاری): دقت کنید بین این دو روش عملگر OR منطقی قرار داده شده که به معنی استفاده از روش THRESH_BINARY و مشخص نمودن آستانه توسط THRESH_OTSU میباشد.
همچنین تابع threshold دو مقدار را در خروجی به ما میدهد یکی مقدار آستانه استفاده شده (متغیر T) و دیگری پیکسلهای تصویر بعد از اعمال آستانهگذاری(متغیر threshInv). خروجی این قسمت به صورت زیر است:

در ادامه مقدار T را چاپ میکنیم:
print(T)
با اجرای کد بالا مقدار 205.0 در کنسول چاپ خواهد شد. این مقدار توسط روش OTSU برای آستانه تصویر تعیین شده است.