پردازش تصویر با پایتون — راهنمای کاربردی

۱۰۷۷۹ بازدید
آخرین به‌روزرسانی: ۱۳ شهریور ۱۴۰۲
زمان مطالعه: ۱۶ دقیقه
پردازش تصویر با پایتون — راهنمای کاربردی

در این مطلب، با مبحث پردازش تصویر با پایتون آشنا خواهید شد. «پردازش تصویر» (Image Processing) یکی از حوزه‌های تأثیرگذار و مهم در «هوش مصنوعی» (Artificial Intelligence) محسوب می‌شود و در حوزه‌های دیگر نظیر «بینایی کامپیوتر» (Computer Vision) و استخراج اطلاعات بامعنی از داده‌های تصویری، نقش بسیار مهمی ایفا می‌کند.

اگرچه بسیاری از کاربران، برنامه‌نویسان و یا توسعه‌دهندگان برنامه‌های کاربردی، از محیط و زبان برنامه‌نویسی «متلب» (MATLAB) جهت توسعه برنامه‌های کاربردی مرتبط با حوزه پردازش تصویر استفاده می‌کنند، با این حال «زبان برنامه‌نویسی پایتون» (Python Programming Language) ابزارهای بسیار مفید و کاربردی جهت پردازش و «دستکاری» (Manipulation) تصاویر دیجیتالی در اختیار این دسته از افراد قرار می‌دهد. در این مطلب، برخی از مهم‌ترین ابزارهای پردازش تصویر با پایتون و دستکاری تصاویر دیجیتالی در این زبان برنامه‌نویسی محبوب مورد بررسی قرار می‌گیرند.

در «علوم کامپیوتر» (Computer Science)، به استفاده از الگوریتم‌های کامپیوتری برای انجام عملیات پردازش تصویر روی تصاویر دیجیتالی، «پردازش تصاویر دیجیتال» (Digital Image Processing) گفته می‌شود. معمولا از الگوریتم‌های پردازش تصاویر دیجیتال جهت «تحلیل تصاویر» (Image Analysis)، دستکاری تصاویر، «بهبود تصاویر» (Image Enhancement)، استخراج اطلاعات مفید از تصاویر و یا بهینه‌سازی «ویژگی‌های مشخصه» (Characteristics) تصاویر دیجیتال استفاده می‌شود. در این مطلب، قرار است مهم‌ترین ابزارهای پردازش تصویر با پایتون معرفی می‌شوند.

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

تاکنون ابزارهای متنوعی برای پردازش تصویر با پایتون معرفی شده‌اند. این دسته از ابزارها، «کتابخانه‌ها» (Libraries) و «بسته‌های» (Packages) برنامه‌نویسی، امکانات بسیار متنوع و مفیدی برای «تبدیل تصاویر» (Image Transformation)، فهمیدن اطلاعات موجود در این داده‌ها و به طور کلی، دستکاری و پردازش تصاویر در اختیار کاربران و برنامه‌نویسان قرار می‌دهند. به عبارت دیگر، ابزارهای پردازش تصویر با پایتون به کاربران این امکان را می‌دهند تا به شکل بسیار ساده و «شهودی» (Intuitive) داده‌های تصویری را تحلیل و اطلاعات بامعنی از آن‌ها استخراج کنند.

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

زبان پایتون می‌تواند به عنوان ابزاری برای انجام عملیات پردازشی روی تصاویر دیجیتالی مورد استفاده قرار بگیرد. از جمله متداول‌ترین فرایندهای پردازش تصویر با پایتون که توسط ابزارها و کتابخانه‌های این زبان برنامه‌نویسی قابل اجرا هستند، می‌توان به مواردی نظیر «برش» (Cropping)، «برعکس کردن» (Flipping)، «چرخاندن» (Rotating)، «قطعه‌بندی تصویر» (Image Segmentation)، «دسته‌بندی تصویر» (Image Classification)، «استخراج ویژگی» (Feature Extraction)، «ترمیم تصاویر» (Image Restoration) و «بازشناسی تصویر» (Image Recognition) اشاره کرد.

زبان برنامه‌نویسی پایتون ابزار بسیار مناسبی برای عملکردهای ذکر شده در حوزه پردازش تصویر محسوب می‌شود. شاید تا چند سال پیش و با توجه به وجود ابزاری نظیر متلب و یکه‌تازی آن در این حوزه، ایده پردازش تصویر با پایتون و استفاده از آن برای دستکاری تصاویر، ایده بسیار ابتدایی و ناکارآمدی محسوب می‌شد. ولی در چند سال اخیر، محبوبیت زبان پایتون به عنوان یک «زبان برنامه‌نویسی علمی» (Scientific Programming Language)، در میان جامعه برنامه‌نویسان به شدت افزایش یافته است. همچنین، محبوبیت روز افزون این زبان برنامه‌نویسی سبب شده است تا ابزارهای بسیار پیشرفته پردازش تصویر، به طور رایگان، به عنوان بخشی از اکوسیستم این زبان برنامه‌نویسی در دسترس کاربران و برنامه‌نویسان قرار بگیرد.

در این مطلب، با 10 ابزار و کتابخانه مهم و پرکاربرد جهت دستکاری و پردازش تصویر با پایتون آشنا خواهید شد. این دسته از ابزارها و کتابخانه‌های برنامه‌نویسی، فرایند تحلیل تصاویر دیجیتال، استخراج اطلاعات با معنی از آن‌ها و در نتیجه، پردازش تصویر با پایتون را برای کاربران و برنامه‌نویسان آسان می‌کنند.

پردازش تصاویر با پایتون با ابزار SciKit-Image

ابزار SciKit-Image، یک بسته برنامه‌نویسی «منبع باز» (Open Source) است که با ساختار آرایه‌ای تعریف شده توسط کتابخانه NumPy کار می‌کند. این ابزار، یکی از مهم‌ترین کتابخانه‌های پردازش تصویر با پایتون محسوب می‌شود که به طور رایگان در دسترس کاربران و برنامه‌نویسان قرار گرفته شده است. در بسته SciKit-Image، مجموعه‌ای از الگوریتم‌ها و ابزارهای پردازش تصویر، جهت استفاده در کاربردهای تحقیقاتی، آموزشی و صنعتی در اختیار کاربران قرار داده شده است.

کار کردن با توابع و الگوریتم‌های SciKit-Image (که جهت پردازش تصویر با پایتون استفاده می‌شوند)، حتی برای کسانی که برنامه‌نویس مبتدی هستند و آشنایی ابتدایی از اکوسیستم پایتون دارند، بسیار ساده و سر راست است. کدهای پیاده‌سازی شده در ابزار SciKit-Image از کیفیت بسیار بالایی برخوردارند و توسط جامعه برنامه‌نویسی بسیار فعال و متشکل از برنامه‌نویسان داوطلب پشتیبانی و به‌روزرسانی می‌شوند.

این بسته را می‌توان با استفاده از skimage در زبان پایتون import کرد. همچنین، بسیاری از توابع و الگوریتم‌های پیاده‌سازی شده را می‌توان در «زیر واحدهای» (Submodules) این بسته برنامه‌نویسی پیدا کرد و مورد استفاده قرار داد. در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط ابزار SciKit-Image قابل انجام است، نمایش داده خواهد شد.

«فیلتر گذاری روی تصاویر» (Image Filtering): با استفاده از این ابزار، می‌توان فیلترهای «بالاگذر» (High Pas) و «پایین گذر» (Low Pass) را جهت انجام پردازش‌هایی نظیر «تشخیص لبه» (Edge Detection) روی تصاویر اعمال کرد.

1import matplotlib.pyplot as plt  
2%matplotlib inline
3       
4from skimage import data,filters
5       
6image = data.coins()   # ... or any other NumPy array!  
7edges = filters.sobel(image)  
8plt.imshow(edges, cmap='gray')

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

«تطبیق الگو» (Template Matching): یکی از ساده‌ترین فرایندهای پردازش تصویر با پایتون و ابزار SciKit-Image، تطبیق الگو است. در کاربردهای پردازش تصویر، برای تشخیص ظاهر شدن یک تصویر الگو در یک یا مجموعه‌ای از تصاویر دیگر، از الگوریتم‌های تطبیق الگو استفاده می‌شود.

1import numpy as np
2import matplotlib.pyplot as plt
3
4from skimage import data
5from skimage.feature import match_template
6
7
8image = data.coins()
9coin = image[170:220, 75:130]
10
11result = match_template(image, coin)
12ij = np.unravel_index(np.argmax(result), result.shape)
13x, y = ij[::-1]
14
15fig = plt.figure(figsize=(8, 3))
16ax1 = plt.subplot(1, 3, 1)
17ax2 = plt.subplot(1, 3, 2)
18ax3 = plt.subplot(1, 3, 3, sharex=ax2, sharey=ax2)
19
20ax1.imshow(coin, cmap=plt.cm.gray)
21ax1.set_axis_off()
22ax1.set_title('template')
23
24ax2.imshow(image, cmap=plt.cm.gray)
25ax2.set_axis_off()
26ax2.set_title('image')
27# highlight matched region
28hcoin, wcoin = coin.shape
29rect = plt.Rectangle((x, y), wcoin, hcoin, edgecolor='r', facecolor='none')
30ax2.add_patch(rect)
31
32ax3.imshow(result)
33ax3.set_axis_off()
34ax3.set_title('`match_template`\nresult')
35# highlight matched region
36ax3.autoscale(False)
37ax3.plot(x, y, 'o', markeredgecolor='r', markerfacecolor='none', markersize=10)
38
39plt.show()

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

کتابخانه Numpy و پردازش تصویر با پایتون

کتابخانه Numpy یکی از کتابخانه‌های برنامه‌نویسی کلیدی در زبان برنامه‌نویسی پایتون محسوب می‌شود که پشتیبانی از «نوع داده‌ای آرایه» (Array Datatype) را در پایتون فراهم می‌کند. این کتابخانه، یکی از مهم‌ترین کتابخانه‌های توسعه داده شده برای کاربردهای پردازش تصویر با پایتون نیز محسوب می‌شود که به طور رایگان در دسترس کاربران و برنامه‌نویسان قرار گرفته شده است.

به طور کلی، یک «تصویر» (Image) یک آرایه استاندارد قابل تعریف توسط کتابخانه Numpy محسوب می‌شود که شامل پیکسل‌های متناظر با نقاط داده‌ای خواهد بود. بنابراین، با استفاده از عملیات پایه‌ای تعریف شده در Numpy نظیر «بخش‌بندی» (Slicing)، «پوشش گذاری» (Masking)، «شاخص گذاری چندگانه» (Fancy Indexing) و سایر موارد، کاربر قادر خواهد بود تا مقادیر پیکسل‌های یک تصویر را تغییر دهد. در کاربرد‌های پردازش تصویر با پایتون و کتابخانه Numpy، می‌توان از کتابخانه skimage برای بارگذاری تصاویر و از کتابخانه Matplotlib جهت نمایش آن‌ها استفاده کرد. در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه Numpy قابل انجام است، نمایش داده خواهد شد.

«پوشش گذاری تصاویر» (Image Masking): یکی از فرایندهای پایه‌ای در پردازش تصویر محسوب می‌شود که به وسیله آن، بخش‌هایی از یک تصویر پنهان و بخش‌های دیگر موجود در تصویر نمایان می‌شوند.

1import numpy as np
2from skimage import data
3import matplotlib.pyplot as plt
4%matplotlib inline
5   
6image = data.camera()  
7type(image)
8numpy.ndarray #Image is a NumPy array: 
9
10mask = image < 87  
11image[mask]=255  
12plt.imshow(image, cmap='gray')

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

کتابخانه SciPy

کتابخانه SciPy یکی دیگر از کتابخانه‌های کلیدی برای برنامه‌نویسی علمی در زبان برنامه‌نویسی پایتون محسوب می‌شود (همانند Numpy). از این کتابخانه مهم نیز می‌توان برای پیاده‌سازی برخی از کاربردهای پردازش تصویر با پایتون استفاده کرد. کتابخانه SciPy حاوی توابع و الگوریتم‌هایی است که به راحتی می‌توان از آن‌ها برای انجام عملیات (ساده) دستکاری و پردازش تصویر با پایتون استفاده کرد.

به طور ویژه، زیر واحد scipy.ndimage توابع عملیاتی لازم جهت انجام عملیات روی آرایه‌های چندبُعدی NumPy (آرایه‌هایی که برای نمایش تصاویر، در قالب آرایه، مورد استفاده قرار می‌گیرند) را فراهم می‌آورد. هم‌اکنون کتابخانه SciPy، توابع لازم برای «فیلتر گذاری خطی و غیرخطی» (Linear and Non-Linear Filtering)، «مورفولوژی باینری» (Binary Morphology)، «درون‌یابی تصویر» (Image Interpolation) و «اندازه‌گیری اشیاء» (Object Measurement) را در اختیار کاربران و برنامه‌نویسان قرار می‌دهد. در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه SciPy قابل انجام است، نمایش داده خواهد شد.

استفاده از کتابخانه SciPy جهت «تار کردن تصویر» (Image Blurring) با استفاده از «فیلتر گاوسی» (Gaussian Filter): یکی از فرایندهای ساده پردازش تصویر با پایتون و کتابخانه SciPy، امکان اعمال فیلتر گاوسی روی تصاویر است که معمولا برای تار کردن (Blurring) تصاویر مورد استفاده قرار می‌گیرد.

1from scipy import misc,ndimage
2   
3face = misc.face()  
4blurred_face = ndimage.gaussian_filter(face, sigma=3)  
5very_blurred = ndimage.gaussian_filter(face, sigma=5)
6   
7#Results  
8plt.imshow(<image to be displayed>)

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

1from scipy.ndimage import gaussian_filter
2from scipy import misc
3import matplotlib.pyplot as plt
4
5a = np.arange(50, step=2).reshape((5,5))
6gaussian_filter(a, sigma=1)
7
8fig = plt.figure()
9plt.gray()  # show the filtered result in grayscale
10ax1 = fig.add_subplot(121)  # left side
11ax2 = fig.add_subplot(122)  # right side
12ascent = misc.ascent()
13result = gaussian_filter(ascent, sigma=5)
14ax1.imshow(ascent)
15ax2.imshow(result)
16plt.show()

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

فیلتر prewitt:

1from scipy import ndimage, misc
2import matplotlib.pyplot as plt
3fig = plt.figure()
4plt.gray()  # show the filtered result in grayscale
5ax1 = fig.add_subplot(121)  # left side
6ax2 = fig.add_subplot(122)  # right side
7ascent = misc.ascent()
8result = ndimage.prewitt(ascent)
9ax1.imshow(ascent)
10ax2.imshow(result)
11plt.show()

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

فیلتر sobel:

1from scipy import ndimage, misc
2import matplotlib.pyplot as plt
3fig = plt.figure()
4plt.gray()  # show the filtered result in grayscale
5ax1 = fig.add_subplot(121)  # left side
6ax2 = fig.add_subplot(122)  # right side
7ascent = misc.ascent()
8result = ndimage.sobel(ascent)
9ax1.imshow(ascent)
10ax2.imshow(result)
11plt.show()

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

کتابخانه‌های PIL و Pillow

کتابخانه PIL که مخفف عبارت Python Imaging Library یا کتابخانه تصویر پایتون است، یکی از کتابخانه‌های پردازش تصویر با پایتون محسوب می‌شود. این کتابخانه، پشتیبانی از عملیات مرتبط با پردازش تصویر نظیر باز کردن، دستکاری و ذخیره‌سازی تصاویر در فرمت‌های مختلف را به زبان پایتون اضافه می‌کند. با این حال، توسعه آن از سال 2009 دچار وقفه شده است.

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

کتابخانه Pillow مجموعه‌ای از قابلیت‌های پردازش تصویر پایه نظیر «عملیات نقطه‌ای» (Point Operations)، فیلتر گذاری با مجموعه‌ای از «کرنل‌های پیچشی» (Convolutional Kernels) تعبیه شده و «تبدیلات فضای رنگی» (Color Space Conversion) را در اختیار کاربر و برنامه‌نویس قرار می‌دهد. در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه‌های PIL و Pillow قابل انجام هستند، نمایش داده خواهد شد.

«بهبود تصاویر» (Image Enhancement): با استفاده از ماژول ImageFilter در کتابخانه Pillow، می‌توان تصاویر دیجیتالی را از  طریق دستکاری مقادیر «کنتراست» (Contrast)، بهبود بخشید.

1from PIL import Image,ImageFilter  
2#Read image
3im = Image.open('image.jpg')
4#Display image  
5im.show()
6   
7from PIL import ImageEnhance  
8enh = ImageEnhance.Contrast(im)  
9enh.enhance(1.8).show("30% more contrast")
105-pillow.png

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

کتابخانه OpenCV-Python

کتابخانه OpenCV که مخفف Open Source Computer Vision Library یا کتابخانه منبع باز بینایی کامپیوتر است، یکی از پراستفاده‌ترین کتابخانه‌های برنامه‌نویسی برای کاربردهای «بینایی کامپیوتر» (Computer Vision) محسوب می‌شود. کتابخانه OpenCV-Python، واسط برنامه‌نویسی کاربردی (API) برای کتابخانه OpenCV در زبان پایتون محسوب می‌شود.

این کتابخانه نه تنها از سرعت بسیار بالایی برخوردار است (زیرا کدهای پیاده‌سازی آن توسط زبان C و C++‎ نوشته شده است)، بلکه کد نویسی برنامه‌های کاربردی مرتبط با پردازش تصویر با پایتون و به‌کاراندازی (Deploy) آن‌ها را تسهیل می‌بخشد. چنین ویژگی‌هایی، کتابخانه OpenCV-Python را به بهترین انتخاب جهت پردازش تصویر با پایتون و پیاده‌سازی برنامه‌های بینایی کامپیوتر در این زبان بدل کرده است (به ویژه اگر برنامه‌های بینایی کامپیوتر توسعه داده شده، به انجام محاسبات ریاضی پیچیده و سنگین نیاز داشته باشند) . در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه OpenCV-Python قابل انجام است، نمایش داده خواهد شد.

«ترکیب تصاویر» (Image Blending): با استفاده از قابلیتی به نام «هرم تصاویر» (Image Pyramid) در OpenCV-Python، می‌توان تصاویر متناظر با یک سیب و یک پرتقال را با یکدیگر ترکیب و یک تصویر جدید درست کرد.

کدهایی که در ادامه آورده‌ایم، به ۲ تصویر «سیب» و «پرتقال» به‌عنوان ورودی نیاز دارند و خروجی نیز با تصاویری به‌نام‌های Direct_blending.jpg   و Pyramid_blending2.jpg  ذخیره می‌شود.

برای دانلود تصاویر مورد نیاز در پروژه «ترکیب تصاویر» اینجا کلیک کنید. لازم به ذکر است که پس از دانلود می‌بایست فایل را از حالت زیپ خارج و تصاویر را در کنار کدها قرار دهید.

1import cv2 as cv
2import numpy as np,sys
3import os
4
5A = cv.imread('apple.jpg')
6B = cv.imread('orange.jpg')
7
8assert A is not None, "file could not be read, check with os.path.exists()"
9assert B is not None, "file could not be read, check with os.path.exists()"
10
11# generate Gaussian pyramid for A
12G = A.copy()
13gpA = [G]
14for i in range(6):
15 G = cv.pyrDown(G)
16 gpA.append(G)
17# generate Gaussian pyramid for B
18G = B.copy()
19gpB = [G]
20for i in range(6):
21 G = cv.pyrDown(G)
22 gpB.append(G)
23# generate Laplacian Pyramid for A
24lpA = [gpA[5]]
25for i in range(5,0,-1):
26 GE = cv.pyrUp(gpA[i])
27 L = cv.subtract(gpA[i-1],GE)
28 lpA.append(L)
29# generate Laplacian Pyramid for B
30lpB = [gpB[5]]
31for i in range(5,0,-1):
32 GE = cv.pyrUp(gpB[i])
33 L = cv.subtract(gpB[i-1],GE)
34 lpB.append(L)
35# Now add left and right halves of images in each level
36LS = []
37for la,lb in zip(lpA,lpB):
38 rows,cols,dpt = la.shape
39 ls = np.hstack((la[:,0:cols//2], lb[:,cols//2:]))
40 LS.append(ls)
41# now reconstruct
42ls_ = LS[0]
43for i in range(1,6):
44 ls_ = cv.pyrUp(ls_)
45 ls_ = cv.add(ls_, LS[i])
46# image with direct connecting each half
47real = np.hstack((A[:,:cols//2],B[:,cols//2:]))
48cv.imwrite('Pyramid_blending2.jpg',ls_)
49cv.imwrite('Direct_blending.jpg',real)

خروجی کدهای فوق، شبیه به تصاویری که در ادامه آورده شده، خواهد بود.
پردازش تصویر با پایتون

کتابخانه SimpleCV

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

ویژگی مهم این کتابخانه این است که کاربران مبتدی، بدون این که لازم باشد تا اطلاعات و دانش کافی در مورد مفاهیمی نظیر «عمق‌های بیتی» (Bit Depths)، فرمت‌های فایلی (File Format)، «فضاهای رنگی» (Color Spaces) و سایر موارد داشته باشند، به راحتی قادر به کار کردن با این کتابخانه و انجام عملیات پردازش تصویر با پایتون خواهند بود. بازه یادگیری کتابخانه SimpleCV به مراتب کوتاه‌تر از OpenCV است. برخی از مزایای این کتابخانه عبارتند از:

  • برنامه‌نویسان مبتدی، به راحتی قادر به نوشتن برنامه‌های مرتبط با بینایی کامپیوتر توسط این کتابخانه هستند.
  • این کتابخانه، توانایی کار کردن با جریان‌های ویدئویی (Video Streams)، تصاویر، فایل‌های ویدئویی و سایر موارد را دارد (به عبارت دیگر، با انواع فایل‌ها و فرمت‌های ویدئویی و تصویری سازگار است).

در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه SimpleCV قابل انجام است، نمایش داده خواهد شد.

تابع «آستانه‌گذاری» (Thresholding): تصویر زیر، نحوه عملکرد تابع Thresholding در کتابخانه SimpleCV را نشان می‌دهد. این تابع، هر کدام از پیکسل‌های یک تصویر را بسته به میزان «روشنایی» (Brightness) آن‌ها، سفید یا سیاه می‌کند.

1from SimpleCV import Image, Color, Display
2
3# Make a function that does a half and half image.
4def halfsies(left,right): 
5    result = left
6    # crop the right image to be just the right side.
7    crop   = right.crop(right.width/2.0,0,right.width/2.0,right.height)
8    # now paste the crop on the left image.
9    result = result.blit(crop,(left.width/2,0))
10    # return the results.
11    return result
12# Load an image from imgur.
13img = Image('http://i.imgur.com/lfAeZ4n.png')
14# binarize the image using a threshold of 90 
15# and invert the results.
16output = img.binarize(90).invert()
17# create the side by side image.
18result = halfsies(img,output)
19# show the resulting image.
20result.show()
21# save the results to a file. 
22result.save('juniperbinary.png')
23@Olhcim

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

«تشخیص لبه» (Edge Detection): در تصویر زیر، نحوه عملکرد تابع تشخیص لبه در کتابخانه SimpleCV نشان داده شده است. این تابع، مقادیر پیکسلی متناظر با لبه‌های تصویر را با رنگ سفید نشان می‌دهد.

1# Make a function that does a half and half image.
2def halfsies(left,right): 
3    result = left
4    # crop the right image to be just the right side.
5    crop   = right.crop(right.width/2.0,0,right.width/2.0,right.height)
6    # now paste the crop on the left image.
7    result = result.blit(crop,(left.width/2,0))
8    # return the results.
9    return result
10# Load an image from imgur.
11img = Image('http://i.imgur.com/lfAeZ4n.png')
12# create an edge image using the Canny edge detector
13# set the first threshold to 160
14output = img.edges(t1=160)
15# generate the side by side image.
16result = halfsies(img,output)
17# show the results.
18result.show()
19# save the output images. 
20result.save('juniperedges.png')

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

مشخص کردن «نقاط کلیدی» (Keypoints) در تصویر: نقاط کلیدی، معمولا مناطق خاص بصری در تصویر هستند که برای انواع مختلفی از کاربردهای بینایی کامپیوتر نظیر «بازسازی سه‌بُعدی» (3D Reconstruction) و «تطبیق تصویر» (Image Matching)‌ مورد استفاده قرار می‌گیرند. پیدا کردن نقاط کلیدی در کتابخانه SimpleCV بسیار ساده است (تابع Image.findKeypoints).

1from SimpleCV import Image, Color, Display
2# load an image from imgur
3img = Image('http://i.imgur.com/lfAeZ4n.png')
4# use a keypoint detector to find areas of interest
5feats = img.findKeypoints()
6# draw the list of keypoints
7feats.draw(color=Color.RED)
8# show the  resulting image. 
9img.show()
10# apply the stuff we found to the image.
11output = img.applyLayers()
12# save the results.
13output.save('juniperfeats.png')

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

کتابخانه Mahotas

کتابخانه Mahotas یکی دیگر از کتابخانه‌های موجود جهت پردازش تصویر با پایتون و پیاده‌سازی برنامه‌های کاربردی مرتبط با حوزه بینایی کامپیوتر است. در این کتابخانه، علاوه بر اینکه توابع پردازش تصویر مرسوم نظیر «فیلتر گذاری» (Filtering) و «عملیات مورفولوژیکی» (Morphological Operations) تعریف شده است، تعدادی توابع بینایی کامپیوتر مدرن جهت «محاسبه ویژگی» (Feature Computation) نظیر «تشخیص نقاط مهم» (Interest Point Detection) و «توصیف کننده‌های محلی» (Local Descriptors) نیز گنجانده شده است.

واسط برنامه‌نویسی این کتابخانه توسط زبان پایتون نوشته شده است (که برای توسعه سریع برنامه‌های کاربردی مرتبط با پردازش تصویر با پایتون و یا برنامه‌های بینایی کامپیوتر بسیار مناسب است)، ولی الگوریتم‌ها در زبان C++‎ پیاده‌سازی شده‌اند (که سبب افزایش سرعت اجرای کدهای این کتابخانه می‌شود). همچنین، کتابخانه Mahotas علاوه بر اینکه سرعت بالایی دارد، «وابستگی‌های» (Dependencies) برنامه‌نویسی بسیار کمی دارد.

در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه Mahotas قابل انجام است، نمایش داده خواهد شد.

حل مسأله «پیدا کردن والی» (Finding Wally) توسط کتابخانه Mahotas: هدف از این مسأله پیدا کردن شخصیت والی (Wally) در تصویر زیر است.

1from pylab import imshow, show
2import mahotas
3import mahotas.demos
4wally = mahotas.demos.load('Wally')
5imshow(wally)
6show()

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

1wfloat = wally.astype(float)
2r,g,b = wfloat.transpose((2,0,1))
3w = wfloat.mean(2)
4pattern = np.ones((24,16), float)
5for i in xrange(2):
6    pattern[i::4] = -1
7v = mahotas.convolve(r-w, pattern)
8mask = (v == v.max())
9mask = mahotas.dilate(mask, np.ones((48,24)))
10np.subtract(wally, .8*wally * ~mask[:,:,None], out=wally, casting='unsafe')
11imshow(wally)
12show()

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

کتابخانه SimpleITK

کتابخانه SimpleITK، یک سیستم منبع باز و «چند سکویی» (Cross-Platform) است که مجموعه‌ای کامل از ابزارهای نرم‌افزاری جهت تحلیل تصاویر دیجیتال را در اختیار برنامه‌نویسان و توسعه‌دهندگان قرار می‌دهد. ویژگی مهم کتابخانه SimpleITK، پشتیبانی از تعداد زیادی مؤلفه نرم‌افزاری است که برای انجام عملیات پردازشی نظیر فیلتر گذاری، «قطعه‌بندی تصاویر» (Image Segmentation) و «ثبت تصویر» (Image Registration) روی تصاویر دیجیتالی مورد استفاده قرار می‌گیرند. این کتابخانه به زبان C++‌‎ نوشته شده است ولی برای دامنه وسیعی از زبان‌های برنامه‌نویسی، از جمله پایتون منتشر شده است.

در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه SimpleITK قابل انجام است، نمایش داده خواهد شد.

کاربرد کتابخانه SimpleITK: مصورسازی فرایند از نوع سخت ثبت تصاویر CT/MR (فرایند Rigid CT/MR Registration)، که توسط کتابخانه SimpleITK و زبان پایتون (پردازش تصویر با پایتون) توسعه داده شده است.

1#
2# Script for generating images illustrating the movement of images and change in
3# similarity metric during registration.
4#
5
6import SimpleITK as sitk
7
8import matplotlib
9matplotlib.use('agg')
10
11import matplotlib.pyplot as plt
12import numpy as np
13
14# Paste the two given images together. On the left will be image1 and on the right image2.
15# image2 is also centered vertically in the combined image.
16def write_combined_image(image1, image2, horizontal_space, file_name):
17    combined_image = sitk.Image((image1.GetWidth() + image2.GetWidth() + horizontal_space,
18                                max(image1.GetHeight(), image2.GetHeight())), 
19                                image1.GetPixelID(), image1.GetNumberOfComponentsPerPixel())
20    combined_image = sitk.Paste(combined_image, image1, image1.GetSize(), (0, 0), (0, 0))
21    combined_image = sitk.Paste(combined_image, image2, image2.GetSize(), (0, 0), 
22                                (image1.GetWidth()+horizontal_space, 
23                                 round((combined_image.GetHeight()-image2.GetHeight())/2)))
24    sitk.WriteImage(combined_image, file_name)
25
26
27# Callback invoked when the StartEvent happens, sets up our new data.
28def start_plot():
29    global metric_values, multires_iterations
30    
31    metric_values = []
32    multires_iterations = []
33
34
35# Callback invoked when the EndEvent happens, do cleanup of data and figure.
36def end_plot():
37    global metric_values, multires_iterations
38    
39    del metric_values
40    del multires_iterations
41    # Close figure, we don't want to get a duplicate of the plot latter on.
42    plt.close()
43
44
45# Callback invoked when the IterationEvent happens, update our data and 
46# save an image that includes a visualization of the registered images and
47# the metric value plot.    
48def save_plot(registration_method, fixed, moving, transform, file_name_prefix):
49
50    #
51    # Plotting the similarity metric values, resolution changes are marked with 
52    # a blue star.
53    #
54    global metric_values, multires_iterations
55    
56    metric_values.append(registration_method.GetMetricValue())                                       
57    # Plot the similarity metric values
58    plt.plot(metric_values, 'r')
59    plt.plot(multires_iterations, [metric_values[index] for index in multires_iterations], 'b*')
60    plt.xlabel('Iteration Number',fontsize=12)
61    plt.ylabel('Metric Value',fontsize=12)
62
63    # Convert the plot to a SimpleITK image (works with the agg matplotlib backend, doesn't work
64    # with the default - the relevant method is canvas_tostring_rgb())
65    plt.gcf().canvas.draw()    
66    plot_data = np.fromstring(plt.gcf().canvas.tostring_rgb(), dtype=np.uint8, sep='')
67    plot_data = plot_data.reshape(plt.gcf().canvas.get_width_height()[::-1] + (3,))
68    plot_image = sitk.GetImageFromArray(plot_data, isVector=True)
69
70    
71    #
72    # Extract the central axial slice from the two volumes, compose it using the transformation
73    # and alpha blend it.
74    #
75    alpha = 0.7
76    
77    central_index = round((fixed.GetSize())[2]/2)
78    
79    moving_transformed = sitk.Resample(moving, fixed, transform, 
80                                       sitk.sitkLinear, 0.0, 
81                                       moving_image.GetPixelIDValue())
82    # Extract the central slice in xy and alpha blend them                                   
83    combined = (1.0 - alpha)*fixed[:,:,central_index] + \
84               alpha*moving_transformed[:,:,central_index]
85
86    # Assume the alpha blended images are isotropic and rescale intensity
87    # Values so that they are in [0,255], convert the grayscale image to
88    # color (r,g,b).
89    combined_slices_image = sitk.Cast(sitk.RescaleIntensity(combined), sitk.sitkUInt8)
90    combined_slices_image = sitk.Compose(combined_slices_image,
91                                         combined_slices_image,
92                                         combined_slices_image)
93
94    write_combined_image(combined_slices_image, plot_image, 0, 
95                         file_name_prefix + format(len(metric_values), '03d') + '.png')
96
97    
98# Callback invoked when the sitkMultiResolutionIterationEvent happens, update the index into the 
99# metric_values list. 
100def update_multires_iterations():
101    global metric_values, multires_iterations
102    multires_iterations.append(len(metric_values))
103
104if __name__ == '__main__':
105
106    # Read the images
107    fixed_image =  sitk.ReadImage("training_001_ct.mha", sitk.sitkFloat32)
108    moving_image = sitk.ReadImage("training_001_mr_T1.mha", sitk.sitkFloat32) 
109
110    # Initial alignment of the two volumes
111    transform = sitk.CenteredTransformInitializer(fixed_image, 
112                                                  moving_image, 
113                                                  sitk.Euler3DTransform(), 
114                                                  sitk.CenteredTransformInitializerFilter.GEOMETRY)
115
116    # Multi-resolution rigid registration using Mutual Information
117    registration_method = sitk.ImageRegistrationMethod()
118    registration_method.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
119    registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
120    registration_method.SetMetricSamplingPercentage(0.01)
121    registration_method.SetInterpolator(sitk.sitkLinear)
122    registration_method.SetOptimizerAsGradientDescent(learningRate=1.0, 
123                                                      numberOfIterations=100, 
124                                                      convergenceMinimumValue=1e-6, 
125                                                      convergenceWindowSize=10)
126    registration_method.SetOptimizerScalesFromPhysicalShift()
127    registration_method.SetShrinkFactorsPerLevel(shrinkFactors = [4,2,1])
128    registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2,1,0])
129    registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()
130    registration_method.SetInitialTransform(transform)
131
132    # Add all the callbacks responsible for ploting
133    registration_method.AddCommand(sitk.sitkStartEvent, start_plot)
134    registration_method.AddCommand(sitk.sitkEndEvent, end_plot)
135    registration_method.AddCommand(sitk.sitkMultiResolutionIterationEvent, update_multires_iterations) 
136    registration_method.AddCommand(sitk.sitkIterationEvent, lambda: save_plot(registration_method, fixed_image, moving_image, transform, 'output/iteration_plot'))
137
138    registration_method.Execute(fixed_image, moving_image)
139© 2019 GitHub, Inc.

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

کتابخانه pgmagick

کتابخانه pgmagick، یک Wrapper توسعه داده شده جهت استفاده از کتابخانه GraphicsMagick در زبان پایتون محسوب می‌شود. کتابخانه GraphicsMagick، یک سیستم پردازش تصویر است که به دلیل امکانات فوق‌العاده و گسترده، به آن «چاقوی سوئیسی» (Swiss Knife) پردازش تصویر نیز گفته می‌شود.

در این کتابخانه، مجموعه‌ای گسترده و قدرتمند از ابزارها و کتابخانه‌های برنامه‌نویسی (جهت پردازش تصویر) تعبیه شده است که از امکاناتی نظیر خواندن، نوشتن و دستکاری تصاویر دیجیتالی در بیش از 88 فرمت تصویری عمده نظیر GIF ،JPEG ،JPEG-2000 ،PNG ،TIFF و سایر موارد پشتیبانی می‌کند.

در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه pgmagick قابل انجام است، نمایش داده خواهد شد.

«مقیاس‌گذاری تصویر» (Image Scaling): 

1from pgmagick import Image, Blob
2
3img = Image(Blob(open('lena_std.jpg').read()), Geometry(200, 200))
4img.scale('200x200')
5img.write('lena_scale.jpg')

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

«استخراج لبه» (Edge Extraction):

1from pgmagick.api import Image
2
3img = Image('lena.jpg')
4img.edge(2)
5img.write('lena_edge.jpg')

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

ابزار Pycairo

ابزار Pycairo، مجموعه‌ای از «مقیدسازی‌های» (Bindings) توسعه داده شده در زبان پایتون، جهت استفاده از کتابخانه گرافیکی Cairo است. کتابخانه Cairo نیز یک کتابخانه گرافیکی دوبُعدی جهت رسم گرافیک‌های برداری محسوب می‌شود. «گرافیک‌های برداری» (Vector Graphics) از آن جهت حائز اهمیت هستند که در اثر فرایندهای پردازشی نظیر «تغییر اندازه» (Resize) یا «تبدیل» (Transformation)، وضوح خود را از دست نمی‌دهند. ابزار Pycairo برای فراخوانی دستورات کتابخانه Cairo در زبان پایتون به کار می‌رود.

در ادامه، برخی از فرایندهای پردازش تصویر با پایتون که توسط کتابخانه Pycairo قابل انجام است، نمایش داده خواهد شد.

رسم خط با استفاده از ابزار Pycairo: خط، یکی از ساده‌ترین گرافیک‌های برداری محسوب می‌شود. برای رسم یک خط، دو تابع از ابزار Pycairo باید فراخوانی شوند. نقطه آغازین خط، توسط فراخوانی تابع move_to()‎ مشخص می‌شود. نقطه پایانی یک خط نیز توسط فراخوانی به تابع line_to()‎ مشخص می‌شود.

1ZetCode PyCairo tutorial 
2
3In this program, we connect all mouse
4clicks with a line.
5
6Author: Jan Bodnar
7Website: zetcode.com 
8Last edited: April 2016
9'''
10
11
12from gi.repository import Gtk, Gdk
13import cairo
14
15
16class MouseButtons:
17    
18    LEFT_BUTTON = 1
19    RIGHT_BUTTON = 3
20    
21    
22class Example(Gtk.Window):
23
24    def __init__(self):
25        super(Example, self).__init__()
26        
27        self.init_ui()
28        
29        
30    def init_ui(self):    
31
32        self.darea = Gtk.DrawingArea()
33        self.darea.connect("draw", self.on_draw)
34        self.darea.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)        
35        self.add(self.darea)
36        
37        self.coords = []
38                     
39        self.darea.connect("button-press-event", self.on_button_press)
40
41        self.set_title("Lines")
42        self.resize(300, 200)
43        self.set_position(Gtk.WindowPosition.CENTER)
44        self.connect("delete-event", Gtk.main_quit)
45        self.show_all()
46        
47    
48    def on_draw(self, wid, cr):
49
50        cr.set_source_rgb(0, 0, 0)
51        cr.set_line_width(0.5)
52        
53        for i in self.coords:
54            for j in self.coords:
55                
56                cr.move_to(i[0], i[1])
57                cr.line_to(j[0], j[1]) 
58                cr.stroke()
59
60        del self.coords[:]            
61                         
62                         
63    def on_button_press(self, w, e):
64        
65        if e.type == Gdk.EventType.BUTTON_PRESS \
66            and e.button == MouseButtons.LEFT_BUTTON:
67            
68            self.coords.append([e.x, e.y])
69            
70        if e.type == Gdk.EventType.BUTTON_PRESS \
71            and e.button == MouseButtons.RIGHT_BUTTON:
72            
73            self.darea.queue_draw()           
74                                                        
75    
76def main():
77    
78    app = Example()
79    Gtk.main()
80        
81        
82if __name__ == "__main__":    
83    main()

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

عملیات Fill و Stroke با استفاده از ابزار Pycairo: در این نمونه کاربرد ابزار Pycairo (نمایش داده شده در شکل زیر)، از عملیات Stroke برای رسم حاشیه‌های شکل و از عملیات Fill برای پر کردن داخل شکل استفاده می‌شود.

1ZetCode PyCairo tutorial 
2
3This code example draws a circle
4using the PyCairo library.
5
6Author: Jan Bodnar
7Website: zetcode.com 
8Last edited: April 2016
9'''
10
11from gi.repository import Gtk
12import cairo
13import math
14
15
16class Example(Gtk.Window):
17
18    def __init__(self):
19        super(Example, self).__init__()
20        
21        self.init_ui()
22        
23        
24    def init_ui(self):    
25
26        darea = Gtk.DrawingArea()
27        darea.connect("draw", self.on_draw)
28        self.add(darea)
29
30        self.set_title("Fill & stroke")
31        self.resize(230, 150)
32        self.set_position(Gtk.WindowPosition.CENTER)
33        self.connect("delete-event", Gtk.main_quit)
34        self.show_all()
35        
36    
37    def on_draw(self, wid, cr):
38
39        cr.set_line_width(9)
40        cr.set_source_rgb(0.7, 0.2, 0.0)
41        
42        w, h = self.get_size()      
43
44        cr.translate(w/2, h/2)
45        cr.arc(0, 0, 50, 0, 2*math.pi)
46        cr.stroke_preserve()
47        
48        cr.set_source_rgb(0.3, 0.4, 0.6)
49        cr.fill()
50        
51    
52def main():
53    
54    app = Example()
55    Gtk.main()
56        
57        
58if __name__ == "__main__":    
59    main()

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

جمع‌بندی‌

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

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

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۴۸ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
opensource.comopencvwisc
۶ دیدگاه برای «پردازش تصویر با پایتون — راهنمای کاربردی»

کد کتابخانه OpenCV-Python با خطا مواجه میشود. لطفا اصلاح بفرمایید

با سلام و احترام؛

ضمن تشکر از ارائه بازخوردتون، کدهای مربوطه، برای پایتون ۳ به‌روز‌رسانی و تست شد.

از همراهی شما با مجله فرادرس بسیار خوشنودیم.

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

سلام وقت بخیر. برای تبدیل عکس به sketch در پایتون باید از چه تابعی استفاده کرد

با سلام خدمت شما…از آموزش شما استفاده کردیم…یک سوال دارم خدمتتون..آیا میشه با پایتون ماکزیمم یا مینیمم نموداری که از تصاویر اینترنتی گرفتم را بدست آورد؟

import numpy as np
import cv2
from PIL import image
کد من اینها رو هم خطا میگیره! چه کنم؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *