در ادامه آموزشهای پردازش تصویر کدگیت، این قسمت به معرفی فیلتر میانگین در پایتون (Mean Filter) میپردازیم. نخست فیلتر میانگین و نحوه کار آن را توضیح داده و در ادامه به پیاده سازی آن در زبان برنامهنویسی پایتون میپردازیم. پیشنهاد میکنیم قبل از مطالعه این آموزش، پیشنیازهای زیر را مطالعه کنید:
- خواندن تصاویر در پایتون
- حلقه For در پایتون
- فیلتر مینیمم در پایتون
- فیلتر ماکزیمم در پایتون
- توابع در پایتون
- لیست در پایتون
همسایه یک پیکسل در تصاویر
همانطور که در آموزشهای گذشته گفته شد تصاویر از پیکسلها تشکیل شده و نحوه نمایش آنها به صورت آرایه دو بعدی است(البته تصاویر RGB سه آرایه دو بعدی داریم!). به تصویر زیر دقت کنید:
در تصویر بالا همسایگان پیکسل X و Y را نمایش دادیم. این نمایش را نمایش همسایگان 8 تایی یک پیکسل تعریف میکنند. همسایه 4 تایی یک پیکسل به صورت زیر نمایش داده میشود:
حال که با تعریف همسایه یک پیکسل آشنا شدیم به سراغ معرفی فیلتر میانگین برویم.
فیلتر میانگین (Mean Filter)
برای بهبود کیفیت یک تصویر و یا تغییر در آن از فیلتر استفاده میشود. فیلتر یک تکنیک است که با اعمال بر روی پیکسلهای یک تصویر، تغییراتی را میتوان در آن اعمال کرد. فیلترها انواع مختلفی دارد که در این قسمت در خصوص فیلتر میانگین یا Mean Filter صحبت میکنیم. این فیلتر همانطور که از نام آن پیداست به دنبال میانگین پیکسلهای یک تصویر است اما سوال اینجاست میانگین کدام پیکسلها؟
برای محاسبه فیلتر میانگین پیکسل X و Y، باید میانگین تمام پیکسلهای همسایه (همسایه 8 تایی) و خود پیکسل (پیکسل X و Y) گرفته شود. فرمول زیر نحوه محاسبه پیکسل X و Y را نشان میدهد(Img لیستی از پیکسلهای تصویر است):
Img[x,y] = (img[x-1,y-1] + img[x-1,y] + img[x-1,y+1] + img[x,y-1] + img[x,y] + img[x,y+1] + img[x+1,y-1] + img[x+1,y] + img[x+1,y+1]) /9
برای محاسبه فیلتر میانگین باید بر روی تمام پیکسلهای تصویر فرمول بالا را اعمال کنیم. یک نکته قابل توجه مرزهای(گوشهها) تصویر است. پیکسلهای گوشه چپ همسایه سمت چپ ندارند همچنین پیکسلهای بالا پایین و راست نیز بهترتیب همسایه بالا، پایین و راست ندارند پس در این صورت چگونه فیلتر میانگین بر روی آنها محاسبه شود؟
برای سادگی کار ما مرز یک تصویر را در نظر نمیگیریم اما راهحلهای مختلفی وجود دارد که این مشکل را برطرف کرده است.
فیلتر میانگین برای حذف نویز مورد استفاده قرار میگیرد و تصویر ما را به اصطلاح تار میکند.
پیاده سازی فیلتر میانگین در پایتون
حال که فرمول فیلتر میانگین را داریم میتوانیم آن را پیاده سازی کنیم. برای پیاده سازی، ما پیکسلهای یک تصویر رنگی را در پایتون خوانده و فیلتر میانگین را بر روی آن اعمال میکنیم. برای اعمال این فیلتر بر روی تصویر رنگی توجه داشته باشید که هر پیکسل از تصویر ما شامل سه عدد R و G و B میباشد پس باید حتما برای هر سه عدد به صورت جداگانه میانگین محاسبه شود.
کد فیلتر میانگین در پایتون به صورت زیر میباشد:
from PIL import Image
import math
def meanFilter (sourceAddress, destAddress):
source = Image.open (sourceAddress)
result = Image.new ('RGB', source.size)
width, height = source.size
pixels = result.load()
for i in range (1, width - 1, 1):
for j in range (1, height - 1, 1):
meanRed = findMeanRed(source, i, j)
meanGreen = findMeanGreen(source, i, j)
meanBlue = findMeanBlue(source, i, j)
pixels[i, j] = (meanRed, meanGreen, meanBlue, 255)
result.save (destAddress, "png")
def findMeanRed (source, x, y):
neighbour = [00] * 9
neighbour[00] = source. getpixel((x - 1, y - 1))[00]
neighbour[1] = source. getpixel((x + 1, y + 1))[00]
neighbour[2] = source. getpixel((x, y - 1))[00]
neighbour[3] = source. getpixel((x, y + 1))[00]
neighbour[4] = source. getpixel((x - 1, y))[00]
neighbour[5] = source. getpixel((x + 1, y))[00]
neighbour[6] = source. getpixel((x - 1, y + 1))[00]
neighbour[7] = source. getpixel((x + 1, y - 1))[00]
neighbour[8] = source. getpixel((x, y))[00]
return math.floor (sum (neighbour) / len(neighbour))
def findMeanGreen (source, x, y):
neighbour = [00] * 9
neighbour[00] = source. getpixel ((x - 1, y - 1))[1]
neighbour[1] = source. getpixel ((x + 1, y + 1))[1]
neighbour[2] = source. getpixel ((x, y - 1))[1]
neighbour[3] = source. getpixel ((x, y + 1))[1]
neighbour[4] = source. getpixel ((x - 1, y))[1]
neighbour[5] = source. getpixel ((x + 1, y))[1]
neighbour[6] = source. getpixel ((x - 1, y + 1))[1]
neighbour[7] = source. getpixel ((x + 1, y - 1))[1]
neighbour[8] = source. getpixel ((x, y))[1]
return math.floor (sum (neighbour) / len(neighbour))
def findMeanBlue (source, x, y):
neighbour = [00] * 9
neighbour[00] = source. getpixel ((x - 1, y - 1))[2]
neighbour[1] = source. getpixel ((x + 1, y + 1))[2]
neighbour[2] = source. getpixel ((x, y - 1))[2]
neighbour[3] = source. getpixel ((x, y + 1))[2]
neighbour[4] = source. getpixel ((x - 1, y))[2]
neighbour[5] = source. getpixel ((x + 1, y))[2]
neighbour[6] = source. getpixel ((x - 1, y + 1))[2]
neighbour[7] = source. getpixel ((x + 1, y - 1))[2]
neighbour[8] = source. getpixel ((x, y))[2]
return math.floor (sum(neighbour) / len(neighbour))
if __name__ == '__main__':
meanFilter('mean filter input.png', 'mean filter otput.png')
print('convert image finished...')
در کد بالا از متدهای زیر استفاده شده است:
- تابع findMeanRed: این تابع اندیسهای یک پیکسل را در ورودی دریافت میکند و میانگین رنگ قرمز همسایگان 8 تایی به همراه پیکسل ورودی را در خروجی به ما میدهد (دقیقا فرمول فیلتر میانگین). نکته قابل ذکر این است که چون پیکسل تصویر ما شامل سه عدد R و G و B بوده باید برای هر سه آنها به طور جداگانه مقدار میانگین را محاسبه کرد.
- تابع findMeanGreen: دقیقا مانند تابع findMeanRed کار میکند فقط در خروجی میانگین رنگهای سبز را به ما میدهد.
- متد findMeanBlue: مانند تابعهای findMeanRed و findMeanGreen بوده اما در خروجی میانگین رنگ آبی پیکسل ورودی و همسایگانش را برمیگرداند.
در صورت اینکه بخشی از کد را متوجه نشدید در کامنت سوال خود را قرار دهید تا شما را راهنمایی کنیم.