- 1. تجزئة وملامح
- 2. التسلسل الهرمي ووضع الاسترجاع
- 3. تقريب ملامح والعثور على بدن محدب
- 4. بدن محدب
- 5. مطابقة الكفاف بالأشكال
- 6. تحديد الأشكال (دائرة ، مستطيل ، مثلث ، مربع ، نجمة)
- 7. كشف الخط
- 8. كشف النقطة
- 9. تصفية النقط - عد الدوائر والقطع الناقص
في الدروس السابقة ، استخدمنا OpenCV لمعالجة الصور الأساسية وقمنا ببعض عمليات تحرير الصور المتقدمة. كما نعلم ، OpenCV هي مكتبة رؤية مفتوحة المصدر تحتوي على واجهات C ++ و Python و Java وتدعم أنظمة التشغيل Windows و Linux و Mac OS و iOS و Android. لذلك يمكن تثبيته بسهولة في Raspberry Pi مع بيئة Python و Linux. ويمكن استخدام Raspberry Pi مع OpenCV والكاميرا المرفقة لإنشاء العديد من تطبيقات معالجة الصور في الوقت الفعلي مثل اكتشاف الوجه وقفل الوجه وتتبع الكائن واكتشاف لوحة أرقام السيارة ونظام أمان المنزل وما إلى ذلك في هذا البرنامج التعليمي سوف نتعلم كيفية القيام بذلك تجزئة الصورة باستخدام OpenCV. العمليات التي سنقوم بتنفيذها مذكورة أدناه:
- تجزئة وخطوط
- التسلسل الهرمي ووضع الاسترجاع
- تقريب معالمها وإيجاد بدنها المحدب
- كونيكس هال
- كفاف مطابقة
- تحديد الأشكال (دائرة ، مستطيل ، مثلث ، مربع ، نجمة)
- كشف الخط
- كشف النقطة
- تصفية النقط - عد الدوائر والحذف
1. تجزئة وملامح
تجزئة الصورة هي عملية نقوم من خلالها بتقسيم الصور إلى مناطق مختلفة. في حين أن المحيطات هي الخطوط أو المنحنيات المستمرة التي تحيط أو تغطي الحدود الكاملة لكائن ما في صورة ما. وهنا سوف نستخدم تقنية تجزئة الصورة تسمى الخطوط العريضة لاستخراج أجزاء الصورة.
كما أن الملامح مهمة جدًا في
- كشف الكائن
- تحليل الشكل
ولديهم مجال واسع جدًا للتطبيق من تحليل الصور في العالم الحقيقي إلى تحليل الصور الطبية مثل التصوير بالرنين المغناطيسي
دعنا نعرف كيفية تنفيذ الخطوط العريضة في opencv ، عن طريق استخراج ملامح المربعات.
استيراد cv2 استيراد numpy كـ np
لنقم بتحميل صورة بسيطة بثلاثة مربعات سوداء
image = cv2.imread ('squares.jpg') cv2.imshow ('إدخال صورة' ، صورة) cv2.waitKey (0)
تدرج الرمادي
رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY)
ابحث عن حواف حاذقة
edged = cv2.Canny (رمادي ، 30200) cv2.imshow ('canny edges'، edged) cv2.waitKey (0)
البحث عن ملامح
# استخدم نسخة من صورتك ، على سبيل المثال - edged.copy () ، نظرًا لأن البحث عن المعالم يغير الصورة # يجب علينا إضافة _ ، قبل الخطوط العريضة كوسيطة فارغة بسبب ترقية إصدار OpenCV _ ، الخطوط العريضة ، التسلسل الهرمي = cv2.findContours (edged، cv2.RETR_EXTERNAL، cv2.CHAIN_APPROX_NONE) cv2.imshow ("الحواف الحادة بعد الكنتور " ، ذات الحواف) cv2.waitKey (0)
طباعة ملف الكنتور لمعرفة ما يتألف منه
طباعة (خطوط) طباعة ('عدد الخطوط الموجودة =' + str (لين (خطوط)))
ارسم كل الخطوط
#use -1 كمعامل ثالث لرسم جميع المخططات cv2.drawContours (image، contours، -1، (0،255،0)، 3) cv2.imshow ('contours'، image) cv2.waitKey (0) cv2. تدمير جميع النوافذ ()
إخراج وحدة التحكم -] ،
] ،
] ،
… ،
] ،
] ،
]] ،
نوع dtype = int32) ،
مجموعة مصفوفة(]،
] ،
] ،
… ،
] ،
] ،
]] ، dtype = int32) ، صفيف (] ،
] ،
] ،
… ،
] ،
] ،
]] ، dtype = int32)]
تم العثور على عدد الخطوط العريضة = 3. إذن ، وجدنا ما مجموعه ثلاثة معالم.
الآن ، في الكود أعلاه ، قمنا أيضًا بطباعة ملف الكنتور باستخدام ، يوضح هذا الملف كيف تبدو هذه الخطوط ، كما هو مطبوع في إخراج وحدة التحكم أعلاه.
في مخرجات وحدة التحكم أعلاه ، لدينا مصفوفة تشبه إحداثيات x و y نقطة. OpenCV يخزن ملامح في قوائم القوائم. يمكننا ببساطة إظهار إخراج وحدة التحكم أعلاه على النحو التالي:
جهاز CONTOUR 1 CONTOUR 2 CONTOUR 3
] ، صفيف (] ، صفيف (] ،
] ،] ،] ،
] ،] ،] ،
… ،… ،… ،
] ،] ،] ،
] ،] ،] ،
]] ، dtype = int32) ،]] ، dtype = int32) ،]] ، dtype = int32)]
الآن ، بما أننا نستخدم دالة الطول في ملف الكنتور ، نحصل على الطول يساوي 3 ، فهذا يعني أن هناك ثلاث قوائم من القوائم في هذا الملف ، أي ثلاثة ملامح.
الآن ، تخيل أن CONTOUR 1 هو العنصر الأول في تلك المصفوفة وأن تلك القائمة تحتوي على قائمة بجميع الإحداثيات وهذه الإحداثيات هي النقاط الموجودة على طول الخطوط التي رأيناها للتو ، مثل المربعات المستطيلة الخضراء.
توجد طرق مختلفة لتخزين هذه الإحداثيات وتسمى طرق التقريب ، وطرق التقريب أساسًا من نوعين
- cv2.CHAIN_APPROX_NONE
- cv2.CHAIN_APPROX_SIMPLE
cv2.CHAIN_APPROX_NONE يخزن كل نقطة الحدود ، لكننا لا نحتاج بالضرورة إلى كل نقاط الحدود ، إذا كانت النقطة تشكل خطًا مستقيمًا ، فنحن نحتاج فقط إلى نقطة البداية ونقطة النهاية على هذا الخط.
يوفر cv2.CHAIN_APPROX_SIMPLE بدلاً من ذلك نقطتي البداية والنهاية لخطوط المحيط ، والنتيجة هي تخزين أكثر كفاءة لمعلومات الكنتور.
_ ، ملامح ، تسلسل هرمي = cv2.findContours (ذو حواف ، cv2.RETR_EXTERNAL ، cv2.CHAIN_APPROX_NONE)
في الكود أعلاه cv2.RETR_EXTERNAL هو وضع الاسترداد بينما cv2.CHAIN_APPROX_NONE هو
طريقة التقريب.
لذلك تعلمنا عن الكفاف وطريقة التقريب ، والآن دعنا نستكشف التسلسل الهرمي ووضع الاسترجاع.
2. التسلسل الهرمي ووضع الاسترجاع
يحدد وضع الاسترجاع التسلسل الهرمي في ملامح مثل الكفاف الفرعي أو المحيط الخارجي أو كل الخطوط.
يوجد الآن أربعة أوضاع استرداد مرتبة حسب أنواع التسلسل الهرمي.
cv2.RETR_LIST - يسترجع كل الأكفة.
cv2.RETR_EXTERNAL - يسترجع المحيط الخارجي أو الخارجي فقط.
cv2.RETR_CCOMP - يسترجع الكل في تسلسل هرمي من مستويين.
cv2.RETR_TREE - يسترجع الكل في تسلسل هرمي كامل.
يتم تخزين التسلسل الهرمي بالتنسيق التالي
الآن دعنا نوضح الفرق بين وضعي الاسترجاع الأولين ، cv2.RETR_LIST و cv2.RETR_EXTERNAL.
استيراد cv2 استيراد numpy كـ np
لنقم بتحميل صورة بسيطة بثلاثة مربعات سوداء
image = cv2.imread ('square donut.jpg') cv2.imshow ('input image'، image) cv2.waitKey (0)
تدرج الرمادي
رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY)
البحث عن حواف الحذق
edged = cv2.Canny (رمادي ، 30200) cv2.imshow ('canny edges'، edged) cv2.waitKey (0)
البحث عن معالم
# استخدم نسخة من صورتك ، على سبيل المثال - edged.copy () ، نظرًا لأن البحث عن ملامح يغير الصورة # علينا إضافة _ ، قبل الخطوط العريضة كوسيطة فارغة بسبب ترقية إصدار السيرة الذاتية المفتوحة _ ، خطوط الكنتور ، التسلسل الهرمي = cv2.findContours (edged، cv2.RETR_EXTERNAL، cv2.CHAIN_APPROX_NONE) cv2.imshow ('حواف مدببة بعد الكنتور ' ، ذات حواف) cv2.waitKey (0)
طباعة ملف الكنتور لمعرفة ما يتألف منه.
طباعة (خطوط) طباعة ('عدد الخطوط الموجودة =' + str (لين (خطوط)))
ارسم كل الخطوط
#use -1 كمعامل ثالث لرسم كل المعالم cv2.drawContours (صورة ، ملامح ، -1 ، (0،255،0) ، 3) cv2.imshow ('contours'، image) cv2.waitKey (0) cv2. تدمير جميع النوافذ
استيراد cv2 استيراد numpy كـ np
لنقم بتحميل صورة بسيطة بثلاثة مربعات سوداء
image = cv2.imread ('square donut.jpg') cv2.imshow ('input image'، image) cv2.waitKey (0)
تدرج الرمادي
رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY)
ابحث عن حواف حاذقة
edged = cv2.Canny (رمادي ، 30200) cv2.imshow ('canny edges'، edged) cv2.waitKey (0)
البحث عن ملامح
# استخدم نسخة من صورتك ، على سبيل المثال - edged.copy () ، نظرًا لأن البحث عن المعالم يغير الصورة # يجب علينا إضافة _ ، قبل الخطوط العريضة كوسيطة فارغة بسبب ترقية إصدار السيرة الذاتية المفتوحة _ ، الخطوط العريضة ، التسلسل الهرمي = cv2.findContours (edged، cv2.RETR_LIST، cv2.CHAIN_APPROX_NONE) cv2.imshow ('canny edges after contouring'، edged) cv2.waitKey (0)
طباعة ملف الكنتور لمعرفة ما يتألف منه.
طباعة (خطوط) طباعة ('عدد الخطوط الموجودة =' + str (لين (خطوط)))
ارسم كل الخطوط
#use -1 كمعامل ثالث لرسم جميع المخططات cv2.drawContours (image، contours، -1، (0،255،0)، 3) cv2.imshow ('contours'، image) cv2.waitKey (0) cv2. تدمير جميع النوافذ ()
لذلك من خلال عرض الرموز أعلاه ، يمكننا أن نرى بوضوح الفرق بين cv2.RETR_LIST و cv2.RETR_EXTERNNAL ، في cv2.RETR_EXTERNNAL ، يتم أخذ الخطوط الخارجية فقط في الاعتبار أثناء تجاهل الخطوط الداخلية.
بينما في cv2.RETR_LIST ، يتم أيضًا أخذ الخطوط الداخلية في الاعتبار.
3. تقريب ملامح والعثور على بدن محدب
لتقريب الكفاف ، يتم تقريب شكل الكنتور على شكل محيط آخر ، والذي قد لا يكون مشابهًا جدًا لشكل الكنتور الأول.
لتقريب نستخدم approxPolyDP ظيفة مكتبة برمجية مفتوحة للرؤية الحاسوبية التي هو موضح أدناه
cv2.approxPolyDP (كفاف ، دقة تقريبية ، مغلق)
المعلمات:
- كونتور - هو الكفاف الفردي الذي نرغب في تقريبه.
- دقة التقريب - معلمة مهمة في تحديد دقة التقريب ، تعطي القيمة الصغيرة تقريبًا دقيقًا ، والقيم الكبيرة تعطي معلومات أكثر عمومية. قاعدة الإبهام الجيدة أقل من 5٪ من محيط الكفاف.
- مغلق - قيمة منطقية توضح ما إذا كان المحيط التقريبي مفتوحًا أم مغلقًا.
دعنا نحاول تقريب شكل بسيط للمنزل
استيراد numpy كـ np import cv2
قم بتحميل الصورة واحتفظ بنسخة
image = cv2.imread ('house.jpg') orig_image = image.copy () cv2.imshow ('original image'، orig_image) cv2.waitKey (0)
التدرج الرمادي وثنائي الصورة
رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY) ret ، عتبة = cv2.threshold (رمادي ، 127255 ، cv2.THRESH_BINARY_INV)
البحث عن ملامح
_ ، معالم ، تسلسل هرمي = cv2.findContours (thresh.copy () ، cv2.RETR_LIST ، cv2.CHAIN_APPROX_NONE)
كرر خلال كل كفاف واحسب المستطيل المحيط
لـ c في الكفاف: x ، y ، w ، h = cv2.boundingRect (c) cv2.rectangle (Orig_image، (x، y)، (x + w، y + h)، (0،0،255)، 2) cv2.imshow ('Bounding rect'، orig_image) cv2.waitKey (0)
كرر خلال كل كفاف واحسب المحيط التقريبي
لـ c in contours:
# حساب الدقة كنسبة مئوية من دقة محيط الكنتور = 0.03 * cv2.arcLength (c ، True) تقريبًا = cv2.approxPolyDP (c ، دقة ، True) cv2.drawContours (image ،، 0، (0،255،0)، 2) cv2.imshow ('تقريبًا polyDP' ، صورة) cv2.waitKey (0) cv2.destroyAllWindows ()
4. بدن محدب
بدن محدب هو في الأساس الحواف الخارجية ، ممثلة برسم خطوط على شكل معين.
يمكن أن يكون أصغر مضلع يمكن وضعه حول الكائن نفسه.
استيراد cv2 استيراد numpy كـ np image = cv2.imread ('star.jpg') رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY) cv2.imshow ('original image'، image) cv2.waitKey (0)
عتبة الصورة
ret، thresh = cv2.threshold (رمادي ، 176،255،0)
ابحث عن ملامح
_ ، معالم ، تسلسل هرمي = cv2.findContours (thresh.copy () ، cv2.RETR_LIST ، cv2.CHAIN_APPROX_NONE)
قم بفرز المحيطات حسب المنطقة ثم قم بإزالة أكبر محيط للإطار
n = len (contours) -1 contours = Sorted (contours، key = cv2.contourArea ، معكوس = خطأ)
كرر من خلال ملامح ورسم بدن محدب
لـ c in contours:
hull = cv2.convexHull (c) cv2.drawContours (image ،، 0، (0،255،0)، 2) cv2.imshow ('convex hull'، image) cv2.waitKey (0) cv2.destroyAllWindows ()
5. مطابقة الكفاف بالأشكال
cv2.matchShapes (قالب الكنتور ، طريقة الكنتور ، معامل الطريقة)
الإخراج - قيمة المطابقة (القيمة الأقل تعني تطابقًا أقرب)
قالب الكنتور - هذا هو كفافنا المرجعي الذي نحاول العثور عليه في صورة جديدة.
الكفاف - الكفاف الفردي الذي نتحقق منه.
الطريقة - نوع المطابقة الكنتورية (1،2،3).
معلمة الطريقة - اتركها بمفردها كـ 0.0 (غير مستخدمة في python opencv)
استيراد cv2 استيراد numpy كـ np
قم بتحميل قالب الشكل أو الصورة المرجعية
template = cv2.imread ('star.jpg'، 0) cv2.imshow ('template'، template) cv2.waitKey (0)
قم بتحميل الصورة المستهدفة بالأشكال التي نحاول مطابقتها
target = cv2.imread ('shapestomatch.jpg') رمادي = cv2.cvtColor (الهدف ، cv2.COLOR_BGR2GRAY)
عتبة كلا الصورتين أولاً قبل استخدام cv2.findContours
ret، thresh1 = cv2.threshold (نموذج ، 127،255،0) ret ، thresh2 = cv2.threshold (رمادي ، 127،255،0)
ابحث عن الملامح في القالب
_، contours، hierarhy = cv2.findContours (thresh1، cv2.RETR_CCOMP، cv2.CHAIN_APPROX_SIMPLE) # نحتاج إلى فرز الكفاف حسب المنطقة حتى نتمكن من إزالة أكبر محيط وهو
مخطط الصورة
Sorted_contours = Sorted (contours، key = cv2.contourArea، reverse = True) # نحن نستخرج ثاني أكبر كفاف والذي سيكون قالبنا contour tempelate_contour = contours # extract the contours from the second target image _، contours، hierarchy = cv2.findContours (thresh2، cv2.RETR_CCOMP، cv2.CHAIN_APPROX_SIMPLE) لـ c in contours: # قم بالقراءة من خلال كل محيط في الصورة المستهدفة واستخدم cv2.matchShape لمقارنة تطابق شكل الكنتور = cv2.matchShapes (tempelate_contour، c، 1،0.0) اطبع ("match") #if ، قيمة المطابقة أقل من 0.15 إذا كانت مطابقة <0.16: الأقرب_كونتور = c else: الأقرب_كونتور = cv2.drawContours (target ،، - 1، (0،255،0)، 3) cv2.imshow ('output') ،استهداف) cv2.waitKey (0) cv2.destroyAllWindows ()
خرج وحدة التحكم -
0.16818605122199104
0.19946910256158912
0.18949760627309664
0.11101058276281539
هناك ثلاث طرق مختلفة بوظيفة رياضية مختلفة ، يمكننا تجربة كل طريقة عن طريق استبدال قيم الطريقة cv2.matchShapes (tempelate_contour ، c ، 1 ، 0.0) والتي تختلف من 1،2 و 3 ، لكل قيمة ستحصل على تطابق مختلف القيم في إخراج وحدة التحكم.
6. تحديد الأشكال (دائرة ، مستطيل ، مثلث ، مربع ، نجمة)
يمكن أيضًا استخدام OpenCV لاكتشاف أنواع مختلفة من الأشكال تلقائيًا من الصورة. باستخدام الكود أدناه ، سنكون قادرين على اكتشاف الدائرة والمستطيل والمثلث والمربع والنجوم من الصورة.
استيراد cv2 استيراد numpy كـ np
قم بتحميل ثم الصور ذات الحجم الرمادي
image = cv2.imread ('forms.jpg') رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY) cv2.imshow ('تحديد الأشكال' ، الصورة) cv2.waitKey (0) ret ، thresh = cv2.threshold (رمادي ، 127،255،1)
استخراج ملامح
_ ، معالم ، تسلسل هرمي = cv2.findContours (thresh.copy () ، cv2.RETR_LIST ، cv2.CHAIN_APPROX_NONE)
بالنسبة لـ cnt in contours:
احصل على مضلعات تقريبية تقريبًا = cv2.approxPolyDP (cnt، 0.01 * cv2.arcLength (cnt، True)، True) إذا كان len (تقريبًا) == 3: shape_name = "Triangle" cv2.drawContours (image ،، 0، (0،255، 0) ، - 1)
ابحث عن مركز الكنتور لوضع النص في المركز
M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (صورة ، اسم الشكل ، (cx-50 ، cy) ، cv2.FONT_HERSHEY_SIMPLEX ، 1 ، (0،0 ، 0)، 1) elif len (تقريبًا) == 4: x، y، w، h = cv2.boundingRect (cnt) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / م)
تحقق لمعرفة ما إذا كان المضلع رباعي الأضلاع مربعًا أم مستطيلًا
# cv2.boundingRect تُرجع العرض والارتفاع الأيسر بالبكسل ، بدءًا من أعلى # الزاوية اليسرى ، بالنسبة للمربع سيكون نفس الشيء تقريبًا إذا كانت abs (wh) <= 3: shape_name = "square" # ابحث عن مركز الكنتور لوضع النص في مركز cv2.drawContours (image ،، 0، (0،125،255)، - 1) cv2.putText (image، shape_name، (cx-50، cy)، cv2.FONT_HERSHEY_SIMPLEX، 1، (0،0،0)، 1) else: shape_name = "Reactangle" # ابحث عن مركز الكنتور لوضع النص في المركز cv2.drawContours (image ،، 0، (0،0،255)، - 1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (image، shape_name، (cx-50، cy)، cv2.FONT_HERSHEY_SIMPLEX، 1، (0،0،0)، 1) elif len (تقريبًا) == 10: shape_name = 'نجمة' cv2.drawContours (image ،، 0، (255،255،0)، - 1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (صورة ، شكل_اسم ، (cx-50، cy)، cv2.FONT_HERSHEY_SIMPLEX، 1، (0،0،0)، 1) elif len (تقريبًا)> = 15: shape_name = ' Circle ' cv2.drawContours (image ،، 0، (0،255،255) ، -1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (صورة ، اسم الشكل ، (cx-50 ، cy) ، cv2.FONT_HERSHEY_SIMPLEX ، 1 ، (0،0،0) ، 1) cv2.imshow ("تحديد الأشكال" ، الصورة) cv2.waitKey (0) cv2.destroyAllWindows ()
7. كشف الخط
يعد اكتشاف الخط مفهومًا مهمًا للغاية في OpenCV ، وله استخدام واعد في العالم الحقيقي. تستخدم السيارات ذاتية القيادة خوارزميات اكتشاف الخطوط لاكتشاف الممرات والطرق.
في الكشف عن الخط سنتعامل مع خوارزميتين ،
- خوارزمية هوغ لاين
- خوارزمية Hough Line Probalistic.
ربما تكون قد تذكرت تمثيل السطر من رياضيات المدرسة الثانوية بالمعادلة ، y = mx + c.
ومع ذلك ، يتم تمثيل الخط في OpenCV بطريقة أخرى
المعادلة أعلاه ρ = xcosӨ + ysincosӨ هي تمثيل OpenCV للخط ، حيث ρ هي المسافة العمودية للخط من الأصل و هي الزاوية التي يتكون منها المعدل الطبيعي لهذا الخط إلى الأصل (تقاس بالراديان ، حيث 1pi راديان / 180 = 1 درجة).
يتم إعطاء وظيفة OpenCV لاكتشاف الخط كـ
cv2.HoughLines (صورة ثنائية الأبعاد ، دقة ، Ө دقة ، عتبة) ، حيث يكون الحد الأدنى للتصويت من أجل اعتباره سطرًا.
الآن دعنا نكتشف خطوط صورة مربعة بمساعدة Hough line function of opencv.
استيراد cv2 استيراد numpy كـ np image = cv2.imread ('box.jpg')
استخراج حواف التدرج الرمادي والدهاء
رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY) حواف = cv2.Canny (رمادي ، 100170 ، فتحة بحجم = 3)
قم بتشغيل خطوط Hough باستخدام دقة rho تبلغ 1 بكسل
#theta دقة (np.pi / 180) وهي 1 درجة # عتبة الخط مضبوطة على 240 (عدد النقاط على الخط) سطور = cv2.HoughLines (حواف ، 1 ، np.pi / 180 ، 240) # نحن نكرر من خلال كل سطر وتحويل إلى تنسيق #REQUIRED التي كتبها cv2.lines (أي التي تتطلب نقطة النهاية) لأنني في مجموعة (0، ليون (خطوط)): لرو، ثيتا في خطوط: و= np.cos (ثيتا) ب = np.sin (ثيتا) x0 = a * rho y0 = b * rho x1 = int (x0 + 1000 * (- b)) y1 = int (y0 + 1000 * (a)) x2 = int (x0-1000 * (-b)) y2 = int (y0-1000 * (a)) cv2.line (صورة ، (x1 ، y1) ، (x2 ، y2) ، (0،255،0) ، 2) cv2.imshow ("hough lines" ، image) cv2.waitKey (0) cv2.destroyAllWindows ()
الآن دعنا نكرر اكتشاف الخط أعلاه مع خوارزمية أخرى لخط هوغ الاحتمالي.
الفكرة وراء خط Hough الاحتمالي هي أخذ مجموعة فرعية عشوائية من النقاط كافية لاكتشاف الخط.
يتم تمثيل دالة OpenCV لخط Hough الاحتمالي بالصيغة cv2.HoughLinesP (صورة ثنائية الأبعاد ، ρ دقة ، دقة ، الحد الأدنى لطول الخط ، الحد الأقصى لفجوة الخط)
الآن دعنا نكتشف خطوط الصندوق بمساعدة خطوط Hough الاحتمالية.
استيراد cv2 استيراد numpy كـ np
حواف حاذقة ودرجات الرمادي مستخرج
image = cv2.imread ('box.jpg') رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY) حواف = cv2.Canny (رمادي ، 50،150 ، فتحة بحجم = 3) # مرة أخرى نستخدم نفس rho ودقة ثيتا #however ، نحدد حدًا أدنى للتصويت (نقاط على طول الخط) يبلغ 100 # وطول خط أدنى يبلغ 5 بكسل وأقصى فجوة بين خطوط 10 بكسل = cv2.HoughLinesP (حواف ، 1 ، np.pi / 180،100،100،10) لـ i في النطاق (0 ، لين (خطوط)): بالنسبة إلى x1 ، y1 ، x2 ، y2 في الأسطر: cv2.line (صورة ، (x1 ، y1) ، (x2 ، y2) ، (0،255،0) ، 3) cv2. imshow ('hough lines'، image) cv2.waitKey (0) cv2.destroyAllWindows
8. كشف النقطة
يمكن وصف Blobs كمجموعة من وحدات البكسل المتصلة التي تشترك جميعها في خاصية مشتركة. يتم وصف طريقة استخدام كاشف البيانات الثنائية الكبيرة OpenCV من خلال مخطط التدفق هذا.
لرسم النقاط الرئيسية ، نستخدم cv2.drawKeypoints الذي يأخذ الوسائط التالية.
cv2.drawKeypoints (صورة الإدخال ، نقاط المفاتيح ، blank_output_array ، اللون ، الأعلام)
أين يمكن أن يكون في الأعلام
cv2.DRAW_MATCHES_FLAGS_DEFAULT
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
و فارغا هنا هو الى حد كبير أي شيء ولكن واحدا تلو مصفوفة واحدة من الأصفار
الآن دعونا نجري اكتشاف النقطة على صورة عباد الشمس ، حيث ستكون النقط هي الأجزاء المركزية للزهرة لأنها شائعة بين جميع الأزهار.
استيراد cv2 import numpy as np image = cv2.imread ('Sunflowers.jpg'، cv2.IMREAD_GRAYSCALE)
قم بإعداد الكاشف مع المعلمات الافتراضية
كاشف = cv2.SimpleBlobDetector_create ()
كشف النقط
keypoints = detector.detect (صورة)
رسم النقط المكتشفة كدوائر حمراء
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS تأكد من أن # حجم الدائرة يتوافق مع حجم blob blank = np.zeros ((1،1)) blobs = cv2.drawKeypoints (صورة ، نقاط رئيسية ، فارغة ، (0،255،255) ، cv2.DRAF_MATCHES)
إظهار نقاط المفاتيح
cv2.imshow ('blobs'، blobs) cv2.waitKey (0) cv2.destroyAllWindows ()
على الرغم من أن الكود يعمل بشكل جيد ، إلا أن بعض النقاط مفقودة بسبب الأحجام غير المتساوية للزهور حيث أن الزهور الموجودة في المقدمة كبيرة مقارنة بالزهور في النهاية.
9. تصفية النقط - عد الدوائر والقطع الناقص
يمكننا استخدام المعلمات لتصفية النقط وفقًا لشكلها وحجمها ولونها. لاستخدام المعلمات مع كاشف blob ، نستخدم وظيفة OpenCV
السيرة الذاتية 2. SimpleBlobDetector_Params ()
سنرى تصفية النقط من خلال هذه المعلمات الأربعة المدرجة أدناه بشكل أساسي:
منطقة
params.filterByArea = True / False params.minArea = pixels params.maxArea = pixels
دائرية
params.filterByCircularity = صحيح / خطأ بارامترات. minCircularity = 1 مثالي ، و 0 معاكسة
التحدب - مساحة النقطة / منطقة بدن محدب
params.filterByConvexity = True / False params.minConvexity = Area
التعطيل
params.filterByInertia = صحيح / خطأ بارامترات. minInertiaRatio = 0.01
الآن دعنا نحاول تصفية النقاط حسب المعلمات المذكورة أعلاه
استيراد cv2 import numpy as np image = cv2.imread ('blobs.jpg') cv2.imshow ('original image'، image) cv2.waitKey (0)
تهيئة الكاشف باستخدام المعلمات الافتراضية
كاشف = cv2.SimpleBlobDetector_create ()
كشف النقط
keypoints = detector.detect (صورة)
ارسم النقط على صورتنا كدوائر حمراء
فارغة = np.zeros ((1،1)) النقط = cv2.drawKeypoints (صورة، النقاط الرئيسية، لم تحدد، (0،0،255)، cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = ليون (النقاط الرئيسية) النص = "لا الكلي للالنقط" + شارع (len ( keypoints)) cv2.putText (blobs، text، (20،550)، cv2.FONT_HERSHEY_SIMPLEX، 1، (100،0،255)، 2)
عرض الصورة مع نقاط المفاتيح blob
cv2.imshow ('blob باستخدام المعلمات الافتراضية' ، blobs) cv2.waitKey (0)
اضبط معلمات التصفية الخاصة بنا
#initialize إعداد المعلمة باستخدام معلمات cv2.SimpleBlobDetector = cv2.SimpleBlobDetector_Params ()
تعيين معلمات تصفية المنطقة
params.filterByArea = True params.minArea = 100
تعيين معلمات التصفية الدائري
params.filterByCircularity = المعلمات الحقيقية. minCircularity = 0.9
تعيين معامل التصفية المحدب
params.filterByConvexity = False params.minConvexity = 0.2
تعيين معلمة تصفية القصور الذاتي
params.filterByInertia = True params.minInertiaRatio = 0.01
إنشاء كاشف مع المعلمة
كاشف = cv2.SimpleBlobDetector_create (بارامز)
كشف النقط
keypoints = detector.detect (صورة)
ارسم النقط على الصور كدوائر حمراء
فارغة = np.zeros ((1،1)) النقط = cv2.drawKeypoints (صورة، النقاط الرئيسية، لم تحدد، (0،255،0)، cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = ليون (النقاط الرئيسية) النص = "لا الكلي للالنقط الدائرية" + str (len ( keypoints)) cv2.putText (blobs، text، (20،550)، cv2.FONT_HERSHEY_SIMPLEX، 1، (0،100،255)، 2)
عرض النقط
cv2.imshow (تصفية النقط الدائرية ، النقط) cv2.waitKey (0) cv2.destroyAllWindows ()
هذه هي الطريقة التي يمكن بها تجزئة الصور في Python-OpenCV. للحصول على فهم جيد لرؤية الكمبيوتر و OpenCV ، راجع المقالات السابقة (الشروع في استخدام Python OpenCV ومعالجات الصور في Python OpenCV وستكون قادرًا على صنع شيء رائع باستخدام Computer Vision.