رزبری پای ماژول دوربین پردازش تصویر

آموزش پردازش تصویر OpenCV با برد رزبری پای – آستانه یابی در تصاویر

نوشته شده توسط آرش کدخدایی

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

 


اهداف پردازش تصویر


این مبحث در پردازش تصویر بسیار مهم بوده و در بسیاری از پروژه ها کاربرد دارد. در این آموزش ، آستانه یابی ساده ، تطبیقی و Otsu را یاد خواهید گرفت و با توابعی از جمله cv.threshold و cv.adaptiveThreshold آشنا خواهیم شد.

 


آستانه یابی ساده Simple Thresholding


در این روش برای هر پیکسل بصورت یکسان عمل میشود و به این صورت عمل میکند که اگر یک پیکسل از آستانه کوچک تر باشد برابر ۰ در غیر این صورت روی حداکثر مقدار تنظیم میشود. برای استفاده از این روش از تابع retval, dst=cv.threshold(src, thresh, maxval, type[, dst]) استفاده میشود. در اینجا تابع ۴ آرگومان اجباری و یک آرگومان اختیاری به عنوان ورودی گرفته و دارای دو خروجی میباشد. اولین آرگومان تابع src میباشد که تصویر ورودی میباشد و حتما باید grayscale باشد. آرگومان دوم مقدار آستانه (thresh) است که برای طبقه بندی مقادیر پیکسل استفاده می شود. آرگومان سوم حداکثر مقدار (maxval) است که به مقادیر پیکسل بیشتر از آستانه اختصاص داده می شود. آرگومان چهارم نوع آستانه یابی است که در پایین انواع آن توضیح داده شده اند:

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

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('gradient.png',0)
ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in xrange(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()

 


آستانه یابی تطبیقی (Adaptive Thresholding)


در روش قبلی ما از روشی استفاده کردیم برای همه پیکسل های تصویر بصورت یکسان عمل شود ولی همیشه این روش جوابگو نیست. بطور مثال اگر تصویر شما دارای نور پردازی های متفاوت باشد. در این حالت از روش آستانه یابی تطبیقی یا سازگار استفاده میکنیم. در این روش، الگوریتم، آستانه یک پیکسل را بر اساس یک ناحیه کوچک در اطراف آن تعیین می کند. بنابراین ما برای مناطق مختلف با همان تصویر آستانه های مختلفی دریافت می کنیم که برای تصاویر با نور متفاوت، نتایج بهتری می دهد. برای این کار از تابع dst=cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) استفاده میکنیم که دارای سه آرگومان بیشتر از تابع قبلی میباشد و یک خروجی بیشتر ندارد.

آرگومان adaptiveMethod تصمیم میگیرد که مقدار آستانه چگونه محاسبه شود و دارای دو نوع زیر است:

  • cv.ADAPTIVE_THRESH_MEAN_C: مقدار آستانه میانگین منطقه، منهای ثابت C
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C: مقدار آستانه مقدار وزنی گاوسی از مقادیر منطقه، منهای ثابت C

آرگومان blockSize اندازه منطقه محله را تعیین می کند و آرگومان C یک ثابت است که از میانگین یا وزن متوسط ​​پیکسل های محله کم می شود. برای فهم تفاوت با روش قبلی به این مثال دقت کنید:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('sudoku.png',0)
img = cv.medianBlur(img,5)
ret,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
th2 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,\
            cv.THRESH_BINARY,11,2)
th3 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
            'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]

for i in xrange(4):
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()

 


روش دو دویی اوتسو Otsu’s Binarization


روش اوتسو نسبت به روش عادی مقدار آستانه را بصورت خودکار انتخاب میکند. در این روش با استفاده از هیستوگرام تصویر و یافتن قله ها این مقدار را پیدا میکند. برای استفاده از این روش دقیقا مانند روش اول عمل کرده تنها به عنوان روش آستانه یابی مورد cv.THRESH_OTSU را اضافه میکنیم. برای فهم بیشتر به کد زیر دقت کنید:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('noisy2.png',0)

ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)

ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)

blur = cv.GaussianBlur(img,(5,5),0)
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)

images = [img, 0, th1,
          img, 0, th2,
          blur, 0, th3]

titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
          'Original Noisy Image','Histogram',"Otsu's Thresholding",
          'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]

for i in xrange(3):
    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
    plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
    plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
    plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])

plt.show()

همانطور که میبینید در روش عادی و استفاده از عدد ۱۲۷ نتیجه را میبینید و در روش اوتسو بصورت عادی نیز میبینید که آستانه یابی بهتر عمل میکند و اما اگر یک فیلتر روی تصویر اعمال کنید تا نویز تصویر کمتر شود نتیجه خیلی خوب بهبود پیدا میکند. در قسمت بعدی خواهیم آموخت که چگونه تصویر را نرم و صاف (Smooth) کنیم.

 

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

 


پروژه و دریافت بن ارسال رایگان


برای دریافت بن خرید از دانشجو کیت، کاربران بایستی با استفاده از وسایل این آموزش، پروژه را اجرا کرده و یا حتی مدار جدیدی تعریف کنید. سپس از اجرای کار فیلم گرفته و در شبکه‌های اجتماعی از جمله آپارات و اینستگرام، با هشتگ‌های دیجی_اسپارک دانشجوکیت digispark daneshjookit منتشر کنند. سپس از طریق بخش نظرات در ادامه همین آموزش، جهت دریافت بن خرید ارسال رایگان به ارزش ۱۲۰۰۰ تومان از دانشجو کیت، لینک را زیر همین پست ارسال کنید.

 

در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی , از وبسایت دیجی اسپارک حمایت کنید.

 

درباره نویسنده

آرش کدخدایی

یک تازه کار علاقه مند به تکنولوژی :)

تبادل نظر و رفع عیب با ثبت دیدگاه