معرفی
Thresholding یک تکنیک ساده و کارآمد برای انجام تقسیم بندی اولیه در یک تصویر و باینریزه کردن آن (تبدیل آن به یک تصویر باینری) است که در آن پیکسل ها یا 0
or 1
(و یا 255
اگر از اعداد صحیح برای نشان دادن آنها استفاده می کنید).
به طور معمول، میتوانید از آستانهگذاری برای انجام تقسیمبندی ساده پسزمینه-پیشزمینه در یک تصویر استفاده کنید، و آن را به انواع روشهای ساده برای هر پیکسل خلاصه میکنید:
if pixel_value > threshold:
pixel_value = MAX
else:
pixel_value = 0
این فرآیند ضروری به عنوان شناخته شده است آستانه باینری. اکنون - راه های مختلفی وجود دارد که می توانید این ایده کلی را تغییر دهید، از جمله معکوس کردن عملیات (تغییر دادن >
با a امضا کنید <
علامت)، تنظیم pixel_value
به threshold
به جای حداکثر مقدار/0 (معروف به کوتاه کردن)، حفظ مقدار pixel_value
خودش اگر بالاتر از threshold
یا اگر زیر آن باشد threshold
.
همه اینها به راحتی در OpenCV پیاده سازی شده اند:
cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
… به ترتیب. اینها روشهای نسبتاً سادهای هستند، زیرا بسیار ساده هستند، زمینه را در تصاویر در نظر نمیگیرند، از اشکال رایجتر و غیره آگاهی دارند. تکنیک.
در حال حاضر، حتی با روش های "ساده لوحانه" - برخی از برای یافتن آستانه های خوب، می توان اکتشافی را به کار برد، که شامل روش Otsu و روش مثلث می شود:
cv2.THRESH_OTSU
cv2.THRESH_TRIANGLE
توجه داشته باشید: آستانه OpenCV یک تکنیک ابتدایی است و به تغییرات نور و شیب، ناهمگونی رنگ و غیره حساس است. بهتر است روی تصاویر نسبتاً تمیز، پس از محو کردن آنها برای کاهش نویز، بدون تغییرات رنگی زیاد در اشیایی که می خواهید قطعه بندی کنید، اعمال شود.
راه دیگر برای غلبه بر برخی از مسائل مربوط به آستانه اولیه با یک مقدار آستانه، استفاده از آستانه تطبیقی که یک مقدار آستانه را بر روی هر منطقه کوچک در یک تصویر اعمال می کند، نه در سطح جهانی.
آستانه گذاری ساده با OpenCV
آستانه گذاری در OpenCV پایتون API از طریق انجام می شود cv2.threshold()
روش - که یک تصویر (آرایه NumPy، نشان داده شده با اعداد صحیح)، آستانه، حداکثر مقدار و روش آستانه را می پذیرد (چگونه threshold
و maximum_value
استفاده می شود):
img = cv2.imread('objects.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blurred = cv2.GaussianBlur(img, (7, 7), 0)
ret, img_masked = cv2.threshold(blurred, 220, 255, cv2.THRESH_BINARY)
کد بازگشتی فقط آستانه اعمال شده است:
print(f"Threshold: {ret}")
در اینجا، از آنجایی که آستانه است 220
و ما از آن استفاده کرده ایم THRESH_BINARY
روش - هر مقدار پیکسل بالا 220
افزایش خواهد یافت 255
، در حالی که هر پیکسل زیر است 220
به پایین خواهد آمد 0
، ایجاد یک تصویر سیاه و سفید، با یک "ماسک"، پوشش اشیاء پیش زمینه.
چرا 220؟ دانستن اینکه تصویر چگونه به نظر می رسد به شما امکان می دهد تا حدس هایی تقریبی در مورد آستانه ای که می توانید انتخاب کنید، انجام دهید. در عمل، به ندرت می خواهید یک آستانه دستی تنظیم کنید، و ما انتخاب آستانه خودکار را در یک لحظه پوشش خواهیم داد.
بیایید نتیجه را ترسیم کنیم! پنجرههای OpenCV ممکن است کمی مشکل باشند، بنابراین تصویر اصلی، تصویر تار و نتایج را با استفاده از Matplotlib ترسیم میکنیم:
fig, ax = plt.subplots(1, 3, figsize=(12, 8))
ax[0].imshow(img)
ax[1].imshow(blurred)
ax[2].imshow(img_masked)
روش های آستانه گذاری
همانطور که قبلا ذکر شد، روشهای مختلفی وجود دارد که میتوانید از مقدار آستانه و حداکثر در یک تابع استفاده کنید. در ابتدا نگاهی به آستانه باینری انداختهایم. بیایید لیستی از روش ها ایجاد کنیم و آنها را یکی یکی اعمال کنیم و نتایج را ترسیم کنیم:
methods = [cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV]
names = ['Binary Threshold', 'Inverse Binary Threshold', 'Truncated Threshold', 'To-Zero Threshold', 'Inverse To-Zero Threshold']
def thresh(img_path, method, index):
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blurred = cv2.GaussianBlur(img, (7, 7), 0)
ret, img_masked = cv2.threshold(blurred, 220, 255, method)
fig, ax = plt.subplots(1, 3, figsize=(12, 4))
fig.suptitle(names[index], fontsize=18)
ax[0].imshow(img)
ax[1].imshow(blurred)
ax[2].imshow(img_masked)
plt.tight_layout()
for index, method in enumerate(methods):
thresh('coins.jpeg', method, index)
THRESH_BINARY
و THRESH_BINARY_INV
معکوس یکدیگر هستند و یک تصویر را باینری می کنند 0
و 255
، اختصاص دادن آنها به پس زمینه و پیش زمینه و بالعکس.
THRESH_TRUNC
تصویر را باینریزه می کند threshold
و 255
.
THRESH_TOZERO
و THRESH_TOZERO_INV
دوتایی کردن بین 0
و مقدار پیکسل فعلی (src(x, y)
). بیایید نگاهی به تصاویر به دست آمده بیندازیم:
راهنمای عملی و عملی ما برای یادگیری Git را با بهترین روش ها، استانداردهای پذیرفته شده در صنعت و برگه تقلب شامل بررسی کنید. دستورات Google Git را متوقف کنید و در واقع یاد گرفتن آی تی!
این روشها به اندازه کافی شهودی هستند - اما، چگونه میتوانیم یک مقدار آستانه خوب را خودکار کنیم، و حتی یک مقدار آستانه خوب به چه معناست؟ اکثر نتایج تا کنون دارای ماسک های غیر ایده آل بودند، با علامت ها و لکه هایی در آنها. این به دلیل تفاوت در سطوح بازتابنده سکهها اتفاق میافتد - به دلیل تفاوت در نحوه بازتاب نور برجستگیها، رنگ آنها یکنواخت نیستند.
ما میتوانیم تا حدی با یافتن آستانه جهانی بهتر با آن مبارزه کنیم.
آستانه گذاری خودکار/بهینه شده با OpenCV
OpenCV از دو روش موثر جستجوی آستانه جهانی - روش Otsu و روش Triangle استفاده می کند.
روش Otsu فرض می کند که روی آن کار می کند دوحالته تصاویر. تصاویر دو حالته تصاویری هستند که هیستوگرام رنگی آنها فقط شامل دو پیک است (یعنی فقط دو مقدار پیکسل مجزا دارند). با توجه به اینکه قله ها هر کدام متعلق به کلاسی مانند "پس زمینه" و "پیش زمینه" هستند - آستانه ایده آل درست در وسط آنها قرار دارد.
تصویر های اعتباری: https://scipy-lectures.org/
میتوانید برخی از تصاویر را با تاریهای گاوسی دووجهیتر کنید، اما نه همه.
یک الگوریتم جایگزین که اغلب عملکرد بهتری دارد، الگوریتم مثلث است که فاصله بین حداکثر و حداقل هیستوگرام سطح خاکستری را محاسبه می کند و یک خط ترسیم می کند. نقطه ای که آن خط حداکثر دورتر از بقیه هیستوگرام است به عنوان آستانه انتخاب می شود:
هر دوی اینها یک تصویر خاکستری را فرض می کنند، بنابراین باید تصویر ورودی را به خاکستری تبدیل کنیم. cv2.cvtColor()
:
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
ret, mask1 = cv2.threshold(blurred, 0, 255, cv2.THRESH_OTSU)
ret, mask2 = cv2.threshold(blurred, 0, 255, cv2.THRESH_TRIANGLE)
masked = cv2.bitwise_and(img, img, mask=mask1)
بیایید تصویر را با هر دو روش اجرا کنیم و نتایج را تجسم کنیم:
methods = [cv2.THRESH_OTSU, cv2.THRESH_TRIANGLE]
names = ['Otsu Method', 'Triangle Method']
def thresh(img_path, method, index):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
ret, img_masked = cv2.threshold(blurred, 0, 255, method)
print(f"Threshold: {ret}")
fig, ax = plt.subplots(1, 3, figsize=(12, 5))
fig.suptitle(names[index], fontsize=18)
ax[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
ax[1].imshow(cv2.cvtColor(gray, cv2.COLOR_BGR2RGB))
ax[2].imshow(cv2.cvtColor(img_masked, cv2.COLOR_BGR2RGB))
for index, method in enumerate(methods):
thresh('coins.jpeg', method, index)
در اینجا، روش مثلث از روش Otsu بهتر عمل می کند، زیرا تصویر دو حالته نیست:
import numpy as np
img = cv2.imread('coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
histogram_gray, bin_edges_gray = np.histogram(gray, bins=256, range=(0, 255))
histogram_blurred, bin_edges_blurred = np.histogram(blurred, bins=256, range=(0, 255))
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].plot(bin_edges_gray[0:-1], histogram_gray)
ax[1].plot(bin_edges_blurred[0:-1], histogram_blurred)
با این حال، واضح است که چگونه روش مثلث توانسته با تصویر کار کند و نتیجه رضایتبخشتری ایجاد کند.
محدودیت های OpenCV Thresholding
آستانه گذاری با OpenCV ساده، آسان و کارآمد است. با این حال، نسبتاً محدود است. به محض معرفی عناصر رنگارنگ، پسزمینههای غیریکنواخت و تغییر شرایط نوری - آستانه جهانی به عنوان یک مفهوم بسیار سفت و سخت میشود.
تصاویر معمولاً برای اینکه یک آستانه کافی نباشد بسیار پیچیده هستند و تا حدی می توان از طریق آن به آن پرداخت آستانه تطبیقی، جایی که بسیاری از آستانه های محلی به جای یک آستانه جهانی استفاده می شود. در حالی که محدود است، آستانه تطبیقی بسیار انعطاف پذیرتر از آستانه جهانی است.
نتیجه
در سالهای اخیر، تقسیمبندی باینری (مانند کاری که در اینجا انجام دادیم) و تقسیمبندی چند برچسبی (جایی که میتوانید تعداد دلخواه کلاسها را کدگذاری کنید) با موفقیت با شبکههای یادگیری عمیق مدلسازی شدهاند که بسیار قدرتمندتر و انعطافپذیرتر هستند. علاوه بر این، آنها می توانند زمینه جهانی و محلی را در تصاویری که در حال تقسیم بندی هستند رمزگذاری کنند. نقطه ضعف این است - برای آموزش آنها به داده ها و همچنین زمان و تخصص نیاز دارید.
برای آستانه گذاری ساده و در حال پرواز، می توانید از OpenCV استفاده کنید. برای تقسیم بندی دقیق و در سطح تولید، باید از شبکه های عصبی استفاده کنید.
رفتن به جلو - یادگیری عمیق عملی برای بینایی کامپیوتر
طبیعت کنجکاو شما باعث می شود که بخواهید جلوتر بروید؟ توصیه می کنیم ما را بررسی کنید دوره: "یادگیری عمیق عملی برای بینایی کامپیوتر با پایتون".
یکی دیگر از دوره های بینایی کامپیوتر؟
ما طبقه بندی ارقام MNIST یا مد MNIST را انجام نخواهیم داد. آنها مدتها پیش نقش خود را انجام دادند. بسیاری از منابع یادگیری قبل از اینکه به معماریهای جعبه سیاه پیشرفته اجازه دهند بار عملکرد را به دوش بکشند، روی مجموعه دادههای پایه و معماریهای پایه تمرکز میکنند.
ما می خواهیم روی آن تمرکز کنیم ابهام زدایی, عملی بودن, درک, شهود و پروژه های واقعی. می خواهند یاد بگیرند چگونه تو می توانی تفاوت ایجاد کنی؟ ما شما را از روشی که مغزمان تصاویر را پردازش میکند تا نوشتن طبقهبندیکننده یادگیری عمیق برای سرطان سینه تا شبکههای یادگیری عمیق که «توهم میکنند»، آموزش اصول و تئوری به شما از طریق کار عملی، و تجهیز شما به دانش و ابزارهایی برای تبدیل شدن به یک متخصص در استفاده از یادگیری عمیق برای حل بینایی کامپیوتر.
داخل چیست؟
- اولین اصول بینایی و نحوه آموزش دیدن کامپیوترها
- وظایف و کاربردهای مختلف بینایی کامپیوتر
- ابزارهای تجارت که کار شما را آسان می کند
- یافتن، ایجاد و استفاده از مجموعه داده ها برای بینایی کامپیوتری
- تئوری و کاربرد شبکه های عصبی کانولوشنال
- مدیریت تغییر دامنه، همزمانی و سایر سوگیری ها در مجموعه داده ها
- آموزش را انتقال دهید و از زمان آموزشی و منابع محاسباتی دیگران به نفع خود استفاده کنید
- ساخت و آموزش پیشرفته ترین طبقه بندی سرطان سینه
- چگونه می توان دوز سالمی از شک و تردید را در ایده های جریان اصلی به کار برد و پیامدهای تکنیک های پذیرفته شده را درک کرد
- تجسم فضای مفهومی ConvNet با استفاده از t-SNE و PCA
- مطالعات موردی چگونگی استفاده شرکت ها از تکنیک های بینایی کامپیوتری برای دستیابی به نتایج بهتر
- ارزیابی صحیح مدل، تجسم فضای پنهان و شناسایی توجه مدل
- انجام تحقیقات دامنه، پردازش مجموعه داده های خود و ایجاد آزمون های مدل
- معماری های پیشرفته، پیشرفت ایده ها، آنچه آنها را منحصر به فرد می کند و نحوه اجرای آنها
- KerasCV - یک کتابخانه WIP برای ایجاد خطوط لوله و مدل های پیشرفته
- نحوه تجزیه و خواندن مقالات و پیاده سازی آنها توسط خودتان
- انتخاب مدل ها بسته به برنامه شما
- ایجاد خط لوله یادگیری ماشینی سرتاسر
- چشم انداز و شهود در تشخیص اشیا با R-CNN سریعتر، رتینا نت، SSD و YOLO
- نمونه و تقسیم بندی معنایی
- تشخیص شی در زمان واقعی با YOLOv5
- آموزش آشکارسازهای شی YOLOv5
- کار با ترانسفورماتورها با استفاده از KerasNLP (کتابخانه WIP با قدرت صنعتی)
- ادغام ترانسفورماتورها با ConvNets برای تولید شرح تصاویر
- عمیق
- بهینه سازی مدل یادگیری عمیق برای بینایی کامپیوتر