المُقدّمة
العتبة هي تقنية بسيطة وفعالة لإجراء تجزئة أساسية في صورة ما ، ولترجمتها (تحويلها إلى صورة ثنائية) حيث تكون وحدات البكسل إما 0
or 1
(أو 255
إذا كنت تستخدم الأعداد الصحيحة لتمثيلها).
عادةً ، يمكنك استخدام العتبة لإجراء تقسيم بسيط للمقدمة الخلفية في صورة ما ، ويتلخص ذلك في المتغيرات في تقنية بسيطة لكل بكسل:
if pixel_value > threshold:
pixel_value = MAX
else:
pixel_value = 0
تُعرف هذه العملية الأساسية باسم عتبة ثنائية. الآن - هناك طرق مختلفة يمكنك من خلالها تعديل هذه الفكرة العامة ، بما في ذلك عكس العمليات (تبديل ملف >
التوقيع مع <
تسجيل) ، ووضع 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
… على التوالى. هذه أساليب "ساذجة" نسبيًا من حيث أنها بسيطة إلى حد ما ، ولا تأخذ في الاعتبار السياق في الصور ، ولديهم معرفة بالأشكال الشائعة ، وما إلى ذلك. بالنسبة لهذه الخصائص - يتعين علينا استخدام تكلفة أكثر وقوة من الناحية الحسابية التقنيات.
الآن ، حتى مع الأساليب "الساذجة" - بعض يمكن وضع الاستدلال في مكانه الصحيح ، لإيجاد عتبات جيدة ، وتشمل هذه طريقة أوتسو وطريقة المثلث:
cv2.THRESH_OTSU
cv2.THRESH_TRIANGLE
ملحوظة: عتبة OpenCV هي تقنية بدائية ، وهي حساسة لتغيرات الإضاءة والتدرجات ، وعدم تجانس الألوان ، وما إلى ذلك. من الأفضل تطبيقها على الصور النظيفة نسبيًا ، بعد تعتيمها لتقليل الضوضاء ، دون تباين كبير في الألوان في الكائنات التي تريد تقسيمها.
هناك طريقة أخرى للتغلب على بعض المشكلات المتعلقة بالحد الأساسي بقيمة عتبة واحدة وهي الاستخدام عتبة التكيف التي تطبق قيمة حدية على كل منطقة صغيرة في الصورة ، وليس على الصعيد العالمي.
عتبة بسيطة مع OpenCV
يتم إجراء العتبة في Python API الخاصة بـ OpenCV عبر ملف 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 ، مع أفضل الممارسات ، والمعايير المقبولة في الصناعة ، وورقة الغش المضمنة. توقف عن أوامر Googling Git وفي الواقع تعلم ذلك!
هذه الأساليب بديهية بما فيه الكفاية - ولكن ، كيف يمكننا أتمتة قيمة عتبة جيدة ، وماذا تعني قيمة "العتبة الجيدة"؟ معظم النتائج حتى الآن تحتوي على أقنعة غير مثالية ، بعلامات وبقع. يحدث هذا بسبب الاختلاف في الأسطح العاكسة للعملات - فهي ليست ملونة بشكل موحد بسبب الاختلاف في كيفية انعكاس الحواف للضوء.
يمكننا ، إلى حد ما ، محاربة هذا من خلال إيجاد عتبة عالمية أفضل.
عتبة تلقائية / محسّنة مع OpenCV
يستخدم OpenCV طريقتين فعالتين للبحث في العتبة العالمية - طريقة أوتسو وطريقة المثلث.
تفترض طريقة أوتسو أنها تعمل ثنائي الوسائط الصور. الصور ثنائية الوسائط هي الصور التي تحتوي الرسوم البيانية اللونية على قمتين فقط (أي تحتوي على قيمتين فقط من قيم البكسل المميزة). بالنظر إلى أن كل من القمم تنتمي إلى فئة مثل "الخلفية" و "المقدمة" - فإن العتبة المثالية تقع في منتصفها مباشرة.
الصورة الائتمان: https://scipy-lectures.org/
يمكنك جعل بعض الصور أكثر ثنائية الوسائط مع تمويه gaussian ، ولكن ليس كلها.
خوارزمية المثلث هي خوارزمية بديلة ، وأفضل أداءً في كثير من الأحيان ، والتي تحسب المسافة بين الحد الأقصى والأدنى لمدرج تكراري المستوى الرمادي وترسم خطًا. يتم اختيار النقطة التي يكون عندها هذا الخط بعيدًا عن بقية المدرج التكراري كحد أقصى:
كلاهما يفترض صورة ذات تدرج رمادي ، لذلك سنحتاج إلى تحويل الصورة المدخلة إلى الرمادي عبر 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)
هنا ، يتفوق أسلوب المثلث على طريقة أوتسو ، لأن الصورة ليست ثنائية الوسائط:
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
يعد استخدام أسلوب العتبة باستخدام OpenCV أمرًا بسيطًا وسهلاً وفعالاً. ومع ذلك ، فهي محدودة إلى حد ما. بمجرد إدخال عناصر ملونة وخلفيات غير موحدة وظروف إضاءة متغيرة - تصبح العتبة العالمية كمفهوم جامدة للغاية.
عادةً ما تكون الصور معقدة للغاية بحيث لا تكفي حد واحد ، ويمكن معالجة ذلك جزئيًا عتبة التكيف، حيث يتم تطبيق العديد من العتبات المحلية بدلاً من عتبات عامة واحدة. على الرغم من محدودية العتبة التكيفية ، إلا أنها أكثر مرونة من العتبة العالمية.
وفي الختام
في السنوات الأخيرة ، تم تصميم التجزئة الثنائية (مثل ما فعلناه هنا) والتجزئة متعددة العلامات (حيث يمكنك الحصول على عدد تعسفي من الفئات المشفرة) بنجاح باستخدام شبكات التعلم العميق ، والتي تكون أكثر قوة ومرونة. بالإضافة إلى ذلك ، يمكنهم ترميز السياق العام والمحلي في الصور التي يقومون بتقسيمها. الجانب السلبي هو - تحتاج إلى بيانات لتدريبهم ، بالإضافة إلى الوقت والخبرة.
للحصول على عتبة بسيطة سريعة ، يمكنك استخدام OpenCV. لتقسيم دقيق على مستوى الإنتاج ، ستحتاج إلى استخدام الشبكات العصبية.
المضي قدمًا - التعلم العميق العملي لرؤية الكمبيوتر
طبيعتك الفضولية تجعلك ترغب في الذهاب إلى أبعد من ذلك؟ نوصي بالتحقق من الدورة: "التعلم العميق العملي لرؤية الكمبيوتر باستخدام Python".
دورة أخرى في الرؤية الحاسوبية؟
لن نقوم بتصنيف أرقام MNIST أو أزياء MNIST. لقد خدموا دورهم منذ وقت طويل. يركز عدد كبير جدًا من موارد التعلم على مجموعات البيانات الأساسية والبنى الأساسية قبل السماح لبنى الصندوق الأسود المتقدمة بتحمل عبء الأداء.
نريد التركيز على إزالة الغموض, التطبيق العملي, فهم, حدس و مشاريع حقيقية. يرغب فى التعلم كيف يمكنك أن تحدث فرقا؟ سنأخذك في جولة من طريقة معالجة أدمغتنا للصور إلى كتابة مصنف تعليمي عميق من الدرجة البحثية لسرطان الثدي إلى شبكات التعلم العميق التي "تهلوس" ، وتعليمك المبادئ والنظرية من خلال العمل العملي ، وتزويدك الدراية والأدوات لتصبح خبيرًا في تطبيق التعلم العميق لحل رؤية الكمبيوتر.
ماذا يوجد في الداخل؟
- المبادئ الأولى للرؤية وكيف يمكن تعليم أجهزة الكمبيوتر "الرؤية"
- مهام وتطبيقات مختلفة للرؤية الحاسوبية
- أدوات التجارة التي ستجعل عملك أسهل
- البحث عن مجموعات البيانات وإنشائها واستخدامها للرؤية الحاسوبية
- نظرية وتطبيق الشبكات العصبية التلافيفية
- التعامل مع تحول المجال والتواجد المشترك والتحيزات الأخرى في مجموعات البيانات
- نقل التعلم والاستفادة من وقت تدريب الآخرين والموارد الحسابية لصالحك
- بناء وتدريب مصنف حديث لسرطان الثدي
- كيفية تطبيق جرعة صحية من الشك على الأفكار السائدة وفهم الآثار المترتبة على التقنيات المعتمدة على نطاق واسع
- تصور "الفضاء المفهوم" لـ ConvNet باستخدام t-SNE و PCA
- دراسات حالة عن كيفية استخدام الشركات لتقنيات الرؤية الحاسوبية لتحقيق نتائج أفضل
- تقييم النموذج المناسب ، تصور الفضاء الكامن وتحديد انتباه النموذج
- إجراء بحث في المجال ومعالجة مجموعات البيانات الخاصة بك وإنشاء اختبارات نموذجية
- أحدث البنيات ، تطور الأفكار ، ما الذي يجعلها فريدة من نوعها وكيفية تنفيذها
- KerasCV - مكتبة العمل قيد التقدم لإنشاء خطوط الأنابيب والنماذج الحديثة
- كيف تحلل وتقرأ الأوراق وتنفذها بنفسك
- اختيار النماذج حسب التطبيق الخاص بك
- إنشاء خط أنابيب تعلم آلي شامل
- المناظر الطبيعية والحدس في اكتشاف الكائنات باستخدام شبكات R-CNN و RetinaNets و SSDs و YOLO أسرع
- المثيل والتجزئة الدلالية
- التعرف على الكائنات في الوقت الفعلي باستخدام YOLOv5
- تدريب كاشفات الأجسام YOLOv5
- العمل مع المحولات باستخدام KerasNLP (مكتبة WIP ذات قوة الصناعة)
- دمج المحولات مع ConvNets لإنشاء تسميات توضيحية للصور
- ديب دريم
- تحسين نموذج التعلم العميق لرؤية الكمبيوتر