آستانه اتسو با استفاده از کتابخانه OpenCV
در این پست، روش اتسو را برای آستانه گذاری خودکار تصویر بررسی می کنیم و نحوه آستانه گیری تصویر با استفاده از کتابخانه OpenCV مورد بررسی قرار می گیرد. قبل از بررسی این مورد لازمه اول در مورد آستانه صحبت کنیم.
آستانه تصویر چیست؟
آستانه گیری تصویر برای باینری کردن آن بر اساس شدت پیکسل استفاده می شود. ورودی الگوریتم آستانه گیری معمولاً یک تصویر در مقیاس خاکستری و یک آستانه است. خروجی یک تصویر باینری است. اگر شدت پیکسل در تصویر ورودی بیشتر از یک آستانه باشد، پیکسل خروجی مربوطه سفید (پیش زمینه) و اگر شدت پیکسل ورودی کمتر یا مساوی آستانه باشد، محل پیکسل خروجی سیاه (پس زمینه) مشخص میشود.
آستانه تصویر در بسیاری از برنامه ها به عنوان مرحله پیش پردازش استفاده می شود. به عنوان مثال، ممکن است از آن در پردازش تصویر پزشکی برای آشکارسازی تومور در ماموگرافی یا محلی سازی یک بلای طبیعی در تصاویر ماهواره ای استفاده کنید. یک چالش با آستانه گذاری ساده این است که شما باید مقدار آستانه را به صورت دستی تعیین کنید. ما می توانیم با امتحان مقادیر مختلف میزان آستانه را به صورت دستی بررسی کنیم اما خسته کننده است و ممکن است در دنیای واقعی با شکست مواجه شود.
بنابراین، ما به راهی برای تعیین خودکار آستانه نیاز داریم. تکنیک اتسو به نام خالق آن Nobuyuki Otsu نمونه خوبی از آستانه گذاری خودکار است. قبل از اینکه به جزئیات تکنیک آستانهگذاری اتسو بپردازیم، بیایید بفهمیم که آستانه تصویر چگونه با تقسیم بندی تصویر ارتباط دارد.
آستانه تصویر در مقابل تقسیم بندی (Segmentation) تصویر
تقسیم بندی تصویر به الگوریتم هایی اطلاق می شود که تصویر را به بخش ها یا گروه های مختلف تقسیم می کنند.
از این نظر، آستانه تصویر ساده ترین نوع تقسیم بندی تصویر است. زیرا تصویر را به دو گروه پیکسل تقسیم می کند. سفید برای پیش زمینه و سیاه برای پس زمینه.
شکل زیر انواع مختلف الگوریتم های تقسیم بندی را نشان می دهد:
بر طیق تصویر فوق، آستانه تصویر (نشان داده شده با استفاده از کادر قرمز) یک نوع تقسیم بندی تصویر است.
آستانه گذاری تصویر به الگوریتم های آستانه تصویر محلی و سراسری تقسیم می شود. در آستانه گذاری سراسری، یک آستانه واحد به صورت سراسری برای کل تصویر استفاده می شود. در آستانه محلی، برخی از ویژگی های قسمتی از مناطق تصویر محلی (به عنوان مثال کنتراست محلی) ممکن است برای انتخاب یک آستانه متفاوت برای بخش های مختلف تصویر استفاده شود.
روش آستانه اتسو یک الگوریتم آستانه گذاری سراسری در تصویر است.
مفهوم آستانه گذاری اتسو
الگوریتم های آستانه گذاری سراسری خودکار معمولاً مراحل زیر را دارند.
1- پردازش تصویر ورودی
2- به دست آوردن هیستوگرام تصویر (توزیع پیکسل)
3- مقدار آستانه T را محاسبه کنید
4-مناطقی از تصویر که از مقدار T بزرگتر هستند را سفید و مناطق مقابل را سیاه قرار دهید.
معمولاً الگوریتم های مختلف در مرحله 3 متفاوت هستند.
نحوه عملکرد آستانه اتسو:
بیایید ایده پشت رویکرد آستانه اتسو را درک کنیم. این روش هیستوگرام تصویر را پردازش می کند. و اشیا را با به حداقل رساندن واریانس هر یک از کلاس ها تقسیم بندی می کند. معمولاً این تکنیک نتایج مناسبی را برای تصاویر دو بعدی تولید می کند. هیستوگرام چنین تصویری شامل دو قله واضح است که محدوده های مختلف شدت را نشان می دهند.
ایده اصلی جداسازی هیستوگرام تصویر با تعریف آستانه که با مینیمم وزنهای واریانس کلاسها مشخص شده است.
کل معادله محاسبه را می توان به شرح زیر توصیف کرد: در حالی که احتمالات دو کلاس تقسیم بر آستانه t هستند، که مقدار آن در محدوده 0 تا 255 است.
در واقع دو گزینه برای یافتن آستانه وجود دارد. اولین مورد این است که واریانس درون کلاس تعریف شده در بالا را به حداقل برسانید،دومین مورد این است که با استفاده از عبارت زیر، واریانس بین کلاس را به حداکثر برسانید:
، در حالی که میانگین کلاس i است.
احتمال برای هر مقدار پیکسل در دو خوشه جدا از هم محاسبه می شود با استفاده از توابع احتمال خوشه به صورت زیر بیان می شود:
لازم به ذکر است که تصویر می تواند به عنوان تابع شدت f (x ، y) ارائه شود، که مقادیر آن در سطح خاکستری است. مقدار پیکسل ها با سطح خاکستری i مشخص شده با i نشان می دهد. تعداد کلی پیکسل های موجود در تصویر n است.
بنابراین ، احتمال وقوع سطح خاکستری i به شرح زیر است:
مقادیر شدت پیکسل برای در هست و برای در هست، در حالی که ماکزیمم مقدار پیکسل ها یا 255 است.
مرحله بعدی بدست آوردن میانگین برای است که بدین صورت بدست میآیند:
حال بیایید معادله فوق واریانس وزنی درون کلاس ها را به خاطر بسپاریم. که با استفاده از روش زیر حاصل میگردد.
اگر آستانه به اشتباه انتخاب شود، واریانس برخی از کلاس ها بزرگ خواهد بود.برای بدست آوردن واریانس کل، فقط باید واریانسهای درون کلاس و بین کلاس را کم کنیم. در حالی که داریم .واریانس کل تصاویر () وابسته به آستانه نیست.
حداکثرسازی واریانس بین کلاسها:
بنابراین، الگوریتم کلی برای حداکثر سازی واریانس بین کلاس می تواند به روش زیر نشان داده شود:
1-هیستوگرام و احتمالات سطح زیادتر را محاسبه کنید.
2-مقداردهی
3-تکرار آستانه احتمالی:
- آپدیت مقادیر
- محاسبه مقادیر واریانس بین کلاس
4-آستانه نهایی مقدار بیشینه.
متدهای پیادهسازی الگوریتم اتسو:
بیایید روش اتسو را پیاده سازی کنیم. این شبیه به راه حل آستانه اتسو از کتابخانه scikit-learn است. بنابراین با خیال راحت از آن به عنوان مرجع استفاده کنید. این تابع بر اساس حداکثر سازی واریانس بین کلاس (همانطور که به خاطر داریم گزینه کوچک سازی نیز وجود دارد) به عنوان OpenCV getThreshVal_Otsu ساخته شده است.
تصویر زیر به عنوان ورودی استفاده می کنیم:
1-خواندن تصویر
اول ، ما باید تصویر را در حالت خاکستری و بهبود احتمالی آن با Gaussian Blurبخوانیم تا نویز را کاهش دهیم:
# Read the image in a grayscale mode image = cv2.imread(img_title, 0) # Apply GaussianBlur to reduce image noise if it is required if is_reduce_noise: image = cv2.GaussianBlur(image, (5, 5), 0)
2- محاسبه آستانه اتسو
آستانه اتسو را محاسبه کنید.
بلوک کد زیر بخش اصلی محاسبه الگوریتم را نشان می دهد که با محاسبه آستانه به پایان می رسد.
# Set total number of bins in the histogram bins_num = 256 # Get the image histogram hist, bin_edges = np.histogram(image, bins=bins_num) # Get normalized histogram if it is required if is_normalized: hist = np.divide(hist.ravel(), hist.max()) # Calculate centers of bins bin_mids = (bin_edges[:-1] + bin_edges[1:]) / 2. # Iterate over all thresholds (indices) and get the probabilities w1(t), w2(t) weight1 = np.cumsum(hist) weight2 = np.cumsum(hist[::-1])[::-1] # Get the class means mu0(t) mean1 = np.cumsum(hist * bin_mids) / weight1 # Get the class means mu1(t) mean2 = (np.cumsum((hist * bin_mids)[::-1]) / weight2[::-1])[::-1] inter_class_variance = weight1[:-1] * weight2[1:] * (mean1[:-1] - mean2[1:]) ** 2 # Maximize the inter_class_variance function val index_of_max_val = np.argmax(inter_class_variance) threshold = bin_mids[:-1][index_of_max_val] print("Otsu's algorithm implementation thresholding result: ", threshold)
نتیجه به دست آمده به قرار زیر است:
Otsu's algorithm implementation thresholding result: 131.982421875
در ادامه همین عمل را با کتابخانه OpenCV به سادگی پیاده سازی میکنیم:
1- خواندن دیتا
اولین مرحله همان است. بارگذاری تصویر در حالت خاکستری با کاهش نویز احتمالی. بیایید نتایج تصویر از پیش پردازش شده و هیستوگرام آن را ببینیم:
در هیستوگرام تصویر زیر ما می توانیم قله یکه و ناحیه نزدیک آن را به وضوح بیان کنیم و در ابتدای مقیاس قله کمی بیان شده را مشاهده کنیم:
2-محاسبه آستانه اتسو
برای اعمال تکنیک اتسو، ما فقط باید از تابع OpenCV threshold با مجموعه THRESH_OTSU استفاده کنیم:
# Applying Otsu's method setting the flag value into cv.THRESH_OTSU. # Use a bimodal image as an input. # Optimal threshold value is determined automatically. otsu_threshold, image_result = cv2.threshold( image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU, ) print("Obtained threshold: ", otsu_threshold)
3-نتیجه
مقدار آستانه تقریباً با مورد بالا (131.98) نزدیک است:
Obtained threshold: 132.0
تصویر نهایی پس از اعمال الگوریتم اتسو به صورت زیر است:
به وضوح مشاهده میکنیم که زمینه و اشیاء اصلی در تصویر از هم جدا شده اند. بیایید یک هیستوگرام برای تصویر باینری به دست آمده ترسیم کنیم:
همانطور که می بینیم، پیکسل های تصویر اکنون به 2 خوشه با مقادیر شدت 0 و 255 تقسیم شده اند.
دیدگاهتان را بنویسید