پردازش تصویر با پایتون قسمت بیست و پنجم

Smoothing_Images

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

۲D Convolution ( Image Filtering )

اهداف این بخش:

  • مات کردن تصاویر با استفاده از فیلتر های پایین گذر مختلف 
  • اعمال فیلتر های سفارشی بر روی تصاویر (۲D convolution)

همانند سیگنالهای تک بعدی، تصاویر(سگنالهای دو بعدی) را هم میتوان با استفاده از فیلترهای پایین گذر(LPF)، بالا گذر (HPF) و … فیلتر کرد. LPF در برطرف کردن نویز یا تارشدن تصویر کمک می کند. HPF در پیدا کردن لبه ها در یک تصویر کمک می کند. کتابخانه OpenCV با استفاده از تابع ()cv2.filter2D، پیمایش (convolve ) یک هسته با یک تصویر را فراهم میکند.

K =  \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1  \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \end{bmatrix}

 

 

فیلتر کردن با هسته فوق نتایج زیر را انجام می دهد . عملیات مثل این است:
برای هر پیکسل در تصویر، یک پنجره ۵×۵(کرنل) بر روی این پیکسل متمرکز است، تمام پیکسلهایی که در این پنجره قرار دارند، جمع می شوند و سپس نتیجه به ۲۵ تقسیم می شود. این محاسبه، معادل میانگین مقادیر پیکسل در داخل آن پنجره است. این عمل برای تمام پیکسل ها در تصویر برای تولید تصویر فیلتر شده انجام می شود. این کد را امتحان کنید و نتیجه را بررسی کنید:

 

import cv2
 import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('opencv_logo.png')
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()

یک آرایه۵×۵ که تمام عناصر آن از یک تشکیل شده باشه، توسط دستور زیر انجام میگیره:
np.ones: آرایه ای از ۱ درست میکند:

np.ones((5,5),np.float32)
array([[ 1., 1., 1., 1., 1.],
[ ۱٫, ۱٫, ۱٫, ۱٫, ۱٫],
[ ۱٫, ۱٫, ۱٫, ۱٫, ۱٫],
[ ۱٫, ۱٫, ۱٫, ۱٫, ۱٫],
[ ۱٫, ۱٫, ۱٫, ۱٫, ۱٫]], dtype=float32)

در نهایت تقسیم بر ۲۵ میشود.

اپن سی وی(opencv) این کار را با تابع cv2.filter2D  انجام میدهد.

cv2.filter2D(img,-1,kernel)

همانطور که مشاهده میکنید این تابع ۳ پارمتر دارد:

 

cv.filter2D (src, dst, ddepth, kernel, anchor = new cv.Point(-1, -1), delta = 0, borderType = cv.BORDER_DEFAULT)

کل پارامترهایی که این تابع میگیره اینها هستن.

۱) src: تصویر ورودی
۲) dst : تصویر خروجی که از نظر اندازه و تعداد کانال با تصویر ورودی یکی است
۳) ddepth: عمق دلخواه تصویر خروجی
۴)کرنل
۵)و….

اگر عمق -۱ باشد یعنی عمق تصویر خروجی باید مانند تصویر ورودی باشد.تصویر ورودی میتونه هر تعداد کانال داشته باشه که به صورت جداگانه پردازش شوند ولی عمق باید  CV_8U, CV_16U, CV_16S, CV_32or  CV_64باشد

دقتdepth :تعداد بیتهای در نظر گرفته شده برای هر پیکسل در کامپیوتر
توجه کنید اگر ddepth مقدار -۱ بگیرد یعنی نتیجه نوع داده تصویر خروجی برابر تصویر ورودی است مثل np.uint8 یعنی ۸بیت ۰-۲۵۵(cv2.CV_8U )
الان تصویر ورودی من دارای اطلاعات زیر میباشد:

img = cv2.imread(‘face.png’)
»> img.dtype
dtype(‘uint8’)

در opencv ،  هر پیکسل در تصویر رنگی،  نماینده ۳ پارامتر(کانال) است: آبی، سبز و قرمز. هر کدام از این پارامتر ها مقدار ۰-۲۵۵ میگیرند. به طور مثال آبی مطلق :

b g r
۲۵۵ ۰ ۰

87

 

تارشدگی تصویر (صاف کردن تصویر)

برای حذف نویز مفید است. در واقع محتوای فرکانس بالا را حذف می کند (به عنوان مثال: نویز، لبه ها)، بنابراین لبه ها ، دچار تغییرات خیلی کمی میشوند .

OpenCV تقریبا چهار نوع تکنیک صاف کردن تصویر را فراهم می کند.

۱)Averaging

این کار توسط پیمایش یک فیلتر جعبه(کرنل) نرمال شده با تصویر ورودی، با استفاده از  cv2.blur () یا cv2.boxFilter () انجام می شود. ما باید عرض و ارتفاع هسته را مشخص کنیم. یک فیلتر جعبه نرمال شده ۳ × ۳ مانند زیر می باشد:

 

7e

import cv2
import numpy as np
from matplotlib import pyplot as plt>
img = cv2.imread('8.png')
blur = cv2.blur(img,(5,5))
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

9

۲) Gaussian Blurring

اینجا به جای فیلتر جعبه، از هسته گوسی  استفاده میشود. تابع مورد استفاده، cv2.GaussianBlur() میباشد. باید عرض و ارتفاع هسته را  که مثبت و فرد است، مشخص کنیم :

blur = cv2.GaussianBlur(img,(5,5),0)

10

 

۳) Median Blurring

بسیار موثر در برابر نویز نمک و فلفل در تصاویر است.  به طور موثر نویز را کاهش می دهد. هسته آن اندازه باید یک عدد صحیح عدد صحیح باشد.

 median = cv2.medianBlur(img,5)

 

13

 

 

 

۴) Bilateral Filtering

فیلتر دو طرفه توسط تابع،   ()cv2.bilateralFilter ، در حذف نویز با حفظ لبه ها بسیار موثر میباشد.

import cv2
 import numpy as np
 from matplotlib import pyplot as pltimg = cv2.imread('14.png')
 temp = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 blur = cv2.bilateralFilter(temp,9,75,75)plt.subplot(121),plt.imshow(temp),plt.title('Original')
 plt.xticks([]), plt.yticks([])
 plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
 plt.xticks([]), plt.yticks([])
 plt.show()

15

ببینید، بافت روی سطح رفته است، اما لبه ها هنوز هم حفظ می شوند.