- كشف الكائن باستخدام SIFT
- الكشف عن الكائن باستخدام ORB
- الرسم البياني للتدرجات الموجهة (HOG's)
- الرسم البياني للتدرجات الموجهة (HOG's) ، خطوة بخطوة:
- المصنفات المتتالية HAAR
- كشف الوجه والعين
- كشف مباشر للوجه والعين
- ضبط المصنفات المتتالية
- كشف السيارات والمشاة في مقاطع الفيديو
لقد بدأنا بتثبيت python OpenCV على windows وقمنا حتى الآن ببعض عمليات معالجة الصور الأساسية وتجزئة الصور واكتشاف الكائنات باستخدام Python ، والتي تمت تغطيتها في البرامج التعليمية أدناه:
- الشروع في استخدام Python OpenCV: التثبيت والمعالجة الأساسية للصور
- التلاعب بالصور في Python OpenCV (الجزء الأول)
- التلاعب بالصور في OpenCV (الجزء 2)
- تجزئة الصورة باستخدام OpenCV - استخراج مناطق معينة من الصورة
تعلمنا أيضًا عن طرق وخوارزميات مختلفة لاكتشاف الكائنات حيث تم تحديد بعض النقاط الرئيسية لكل كائن باستخدام خوارزميات مختلفة. في هذا البرنامج التعليمي ، سنستخدم تلك الخوارزميات لاكتشاف الكائنات الواقعية ، وهنا سنستخدم SIFT و ORB للكشف.
كشف الكائن باستخدام SIFT
هنا سيتم اكتشاف الكائن باستخدام دفق كاميرا الويب المباشر ، لذلك إذا تعرف على الكائن ، فسيتم ذكر objet الذي تم العثور عليه. في الكود ، يتم تشغيل الجزء الرئيسي من خلال الوظيفة التي تسمى كاشف SIFT ، وتتم معظم المعالجة بواسطة هذه الوظيفة.
وفي النصف الآخر من الكود ، نبدأ بفتح تدفق كاميرا الويب ، ثم نقوم بتحميل قالب الصورة ، أي الصورة المرجعية ، أي أن البرنامج يبحث بالفعل من خلال تدفق كاميرا الويب.
بعد ذلك ، نلتقط الصور باستمرار من دفق كاميرا الويب بمساعدة حلقة أثناء لانهائية ، ثم نلتقط الارتفاع والعرض المقابل لإطار كاميرا الويب ، ثم بعد ذلك نحدد معلمات منطقة الاهتمام (ROI) المربع الذي فيه يمكن أن يتلاءم الكائن الخاص بنا من خلال أخذ الارتفاع والعرض المقابل لإطار كاميرا الويب. ثم نرسم المستطيل من معلمات ROI التي حددناها أعلاه. ثم أخيرًا قم بقص المستطيل وإدخاله في جزء كاشف SWIFT من الكود.
الآن يحتوي كاشف SIFT بشكل أساسي على مدخلين ، أحدهما هو الصورة المقصوصة والآخر هو قالب الصورة الذي حددناه مسبقًا ثم يعطينا بعض التطابقات ، لذا فإن المطابقات هي أساسًا عدد الكائنات أو نقاط المفاتيح المتشابهة في الصورة التي تم اقتصاصها والصورة المستهدفة. ثم نحدد قيمة عتبة للمطابقات ، إذا كانت قيمة المطابقات أكبر من العتبة ، نضع الصورة الموجودة على شاشتنا باللون الأخضر لمستطيل ROI.
الآن دعنا نعود إلى الجزء الرئيسي من الكود ، الوظيفة التي تسمى كاشف SIFT ، فهي تأخذ المدخلات كصورتين واحدة هي الصورة التي تبحث فيها عن الكائن والأخرى هي الكائن الذي نحاول مطابقته إلى (نموذج الصورة). ثم قم بقياس الصورة الأولى باللون الرمادي وحدد قالب الصورة كصورة ثانية. ثم نقوم بإنشاء كائن كاشف SIFT وتشغيل وظيفة الكشف والحساب OpenCV SIFT ، وذلك لاكتشاف النقاط الرئيسية وحساب الواصفات ، فالواصفات هي في الأساس المتجهات التي تخزن المعلومات حول النقاط الأساسية ، ومن المهم حقًا أثناء قيامنا بالمطابقة بين واصفات الصور.
ثم حدد المطابق المستند إلى FLANN ، فنحن لا ندخل في النظرية الرياضية للمطابقة التي تقف وراءها ، ولكن يمكنك بسهولة البحث في Google عنها. أولاً ، حدد الفهرس kdtree إلى الصفر ، ثم قمنا بتعيين معلمات الفهرس والبحث في تنسيق القاموس ، ونقوم فقط بتعريف الخوارزمية التي سنستخدمها وهي KDTREE ، وعدد الأشجار التي سنستخدمها ، وكلما زاد عدد الشجرة نحن نستخدم الأمر الأكثر تعقيدًا وأبطأ. وفي معلمة البحث ، حدد عدد عمليات التحقق ، والتي تمثل أساسًا عدد المطابقات التي ستكتمل.
ثم قم بإنشاء كائن المطابق المستند إلى FLANN عن طريق تحميل المعلمة التي حددناها مسبقًا وهي معلمات الفهرس ومعلمات البحث وبناءً على ذلك ، قم بإنشاء المطابق المستند إلى FLANN ، وهو مطابقة KNN حيث KNN هي أقرب جيران K ، وهي في الأساس طريقة حيث نحن نبحث عن أقرب المطابقات والواصفات ونقوم بالمطابقة مع ثابت التهيئة k. الآن هذا المطابق المستند إلى FLANN يعرض عدد التطابقات التي نحصل عليها.
المطابقة المستندة إلى FLANN هي مجرد تقريب ، لزيادة دقة المطابق المستند إلى FLANN ، نقوم بإجراء اختبار نسبة Lowe وما يفعله هو البحث عن المطابقات من المطابق القائم على knn flann وتحديد بعض معلمات matric وهي المسافة هنا ، والتي تعتبر المسافة دالة فارغة ، وبمجرد استيفائها للمعايير ، قم بإلحاق التطابقات بالمطابقات الجيدة وإرجاع التطابقات الجيدة التي تم العثور عليها ، وبالتالي يخبر دفق الفيديو المباشر عدد التطابقات الموجودة في زاوية الشاشة.
الآن دعونا نلقي نظرة على رمز الوصف أعلاه:
import cv2 import numpy as np def sift_detector (new_image، image_template): # الوظيفة التي تقارن الصورة المدخلة بالقالب # ثم تقوم بإرجاع عدد مطابقة SIFT بينها image1 = cv2.cvtColor (new_image، cv2.COLOR_BGR2GRAY) image2 = image_template # Create كائن كاشف SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # الحصول على نقاط المفاتيح والواصفات باستخدام SIFT keypoints_1، descriptors_1 = sift.detectAndCompute (image1، None) keypoints_2، descriptors_2 = sift.detectAnd (image2) لا شيء) # تحديد معلمات Flann Matcher FLANN_INDEX_KDTREE = 0 index_params =ict (الخوارزمية = FLANN_INDEX_KDTREE ، الأشجار = 3) search_params =ict (الشيكات = 100) # إنشاء كائن Flann Matcher flann = cv2.FlannBasedMatcher (index_params ، search_params) # الحصول على التطابقات باستخدام K-Nearest Neighbor Method # النتيجة "المطابقات" هي عدد التطابقات المتشابهة الموجودة في كلتا الصورتين المتطابقتين = flann.knnMatch (descriptors_1، descriptors_2، k = 2) # تخزين التطابقات الجيدة باستخدام اختبار نسبة Lowe good_matches = لـ m ، n في المطابقات: إذا كانت m.distance <0.7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # قم بتحميل قالب الصورة الخاص بنا ، هذه هي صورتنا المرجعية image_template = cv2.imread ('phone.jpg'، 0) بينما True: # احصل على صور كاميرا الويب ret، frame = cap.read () # احصل على ارتفاع وعرض إطار كاميرا الويب ، والعرض = frame.shape # تحديد أبعاد صندوق العائد على الاستثمار top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # ارسم نافذة مستطيلة لمنطقتنا التي تهمنا cv2.rectangle (frame، (top_left_x، top_left_y))، (bottom_right_x، bottom_right_y)، 255، 3) # نافذة اقتصاص الملاحظة التي حددناها أعلاه اقتصاص = إطار # قلب اتجاه الإطار أفقيًا إطار = cv2.flip (إطار ، 1) # احصل على عدد مباريات SIFT المطابقات = sift_detector (اقتصاص ، نموذج_الصورة) # عرض حالة سلسلة تظهر لا الحالي. من المطابقات cv2.putText (frame، str (match)، (450،450)، cv2.FONT_HERSHEY_COMPLEX، 2، (0،255،0)، 1) # العتبة الخاصة بنا للإشارة إلى كاشف الكائن # نحن نستخدم 10 لأن كاشف SIFT يُرجع مواضع خاطئة صغيرة العتبة = 10 # إذا تجاوزت المطابقات الحد الخاص بنا ، فسيتم اكتشاف الكائن في حالة التطابق> العتبة: cv2.rectangle (frame، (top_left_x، top_left_y)، (bottom_right_x، bottom_right_y)، (0،255،0)، 3) cv2.putText (frame) ، 'Object Found'، (50،50)، cv2.FONT_HERSHEY_COMPLEX، 2، (0،255،0)، 2) cv2.imshow ('Object Detector using SIFT'، frame) إذا كان cv2.waitKey (1) == 13: رقم 13 هو إدخال الحد الأقصى لكسر المفتاح. الإصدار () cv2.destroyAllWindows ()
الكشف عن الكائن باستخدام ORB
يعد اكتشاف الكائنات باستخدام SIFT رائعًا ودقيقًا إلى حد كبير ، لأنه يولد عددًا دقيقًا من التطابقات استنادًا إلى النقاط الأساسية ، ومع ذلك فهو حاصل على براءة اختراع مما يجعل من الصعب استخدامه للتطبيقات التجارية ، والمخرج الآخر لذلك هو خوارزمية ORB لاكتشاف الكائن.
على غرار طريقة اكتشاف الأشياء بواسطة SIFT التي قسمنا فيها البرنامج إلى قسمين ، سيتم اتباع نفس الشيء هنا.
أولاً ، نحدد الوظيفة ORB_detector التي تأخذ مدخلين أحدهما هو صورة البث المباشر القادمة من كاميرا الويب والآخر هو قالب الصورة الذي على أساسه سنطابق صورتنا. ثم نقوم بتدريج صورة كاميرا الويب الخاصة بنا ثم نقوم بتهيئة كاشف ORB الخاص بنا ، ونقوم بتعيينه هنا عند 1000 نقطة رئيسية ومعلمات القياس 1.2. يمكنك التلاعب بهذه المعلمات بسهولة ، ثم اكتشاف نقاط المفاتيح (kp) والواصفات (des) لكل من الصور والمعلمة الثانية التي نحددها في وظيفة اكتشاف وحساب هي NONE ، فهي تطلب استخدام قناع الصورة أم لا و نحن ننكر ذلك هنا.
ثم انتقل إلى الكاشف سابقًا كنا نستخدم المطابق المستند إلى FLANN ، ولكن هنا سنستخدم BFMatcher وداخل BFMatcher نحدد معلمتين أحدهما هو NORM_HAMMING والآخر هو التحقق المتقاطع الذي قيمته TRUE.
ثم احسب التطابقات بين هاتين الصورتين باستخدام الواصفات المحددة أعلاه ، والتي تُرجع في جميع الحالات عدد المطابقات لأن هذه المطابقات ليست تقريبية وبالتالي ليست هناك حاجة لإجراء اختبار نسبة Lowe ، بدلاً من ذلك نقوم بفرز التطابقات بناءً على المسافة ، على الأقل كلما زادت المسافة كلما كان التطابق أفضل (هنا المسافة تعني المسافة بين النقطتين) ، وفي النهاية نرجع عدد التطابقات باستخدام دالة الطول.
وفي الوظيفة الرئيسية ، قمنا بتعيين العتبة على قيمة أعلى بكثير ، لأن كاشف الجرم السماوي يولد الكثير من الضوضاء.
الآن دعونا نلقي نظرة على الكود الخاص باكتشاف ORB القائم
import cv2 import numpy as np def ORB_detector (new_image، image_template): # الوظيفة التي تقارن صورة الإدخال بالقالب # ثم تقوم بإرجاع عدد تطابقات ORB بينهما image1 = cv2.cvtColor (new_image، cv2.COLOR_BGR2GRAY) # Create ORB detector with 1000 نقطة أساسية مع عامل هرم قياس 1.2 orb = cv2.ORB_create (1000، 1.2) # اكتشاف النقاط الأساسية للصورة الأصلية (kp1، des1) = orb.detectAndCompute (image1، None) # اكتشاف النقاط الأساسية للصورة التي تم تدويرها (kp2، des2) = orb.detectAndCompute (image_template، None) # إنشاء المطابق # ملاحظة لم نعد نستخدم مطابقة Flannbased bf = cv2.BFMatcher (cv2.NORM_HAMMING، crossCheck = True) # هل تطابق المطابقات = bf.match (des1، des2) # قم بترتيب المباريات بناءً على المسافة. أقل مسافة # هي أفضل المطابقات = مرتبة (تطابقات ، مفتاح = lambda val: val.distance) عودة len (تطابق) cap = cv2.VideoCapture (0) # قم بتحميل قالب الصورة ، هذه هي الصورة المرجعية image_template = cv2.imread ("phone.jpg '، 0) # image_template = cv2.imread (' الصور / kitkat.jpg '، 0) في حين صحيح: # الحصول على كاميرا الصور متقاعد، والإطار = cap.read () # الحصول على الطول والعرض من إطار الكاميرا في ارتفاع ، العرض = frame.shape # تحديد أبعاد صندوق العائد على الاستثمار (لاحظ أن بعض هذه الأشياء يجب أن تكون خارج الحلقة) top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # رسم نافذة مستطيلة لدينا منطقة الاهتمام cv2.rectangle (frame، (top_left_x، top_left_y)، (bottom_right_x، bottom_right_y)، 255، 3) # اقتصاص نافذة الملاحظة التي حددناها أعلاه اقتصاصًا = إطار # انعكاس إطار اتجاه أفقي إطار = cv2.flip (إطار ، 1) # احصل على عدد مطابقات ORB المطابقة = ORB_detector (اقتصاص ، image_template) # عرض سلسلة الحالة التي تعرض الرقم الحالي. من التطابقات output_string = "Matches =" + str (تطابق) cv2.putText (frame، output_string، (50،450)، cv2.FONT_HERSHEY_COMPLEX، 2، (250،0،150)، 2) # حدنا للإشارة إلى اكتشاف الكائن # بالنسبة للصور الجديدة أو ظروف الإضاءة ، قد تحتاج إلى تجربة بعض الشيء # ملاحظة: كاشف ORB للحصول على أفضل 1000 تطابق ، 350 هو في الأساس حد أدنى 35 ٪ للتطابق = 250 # إذا تجاوزت المطابقات لدينا عتبة ثم تم اكتشاف الكائن إذا كانت التطابقات> عتبة: cv2.rectangle (frame، (top_left_x، top_left_y)، (bottom_right_x، bottom_right_y)، (0،255،0)، 3) cv2.putText (frame، 'Object Found'، (50 ، 50)، cv2.FONT_HERSHEY_COMPLEX، 2، (0،255،0)، 2) cv2.imshow ('Object Detector using ORB'، frame) إذا كان cv2.waitKey (1) == 13: # 13 هو إدخال مفتاح كسر الغطاء.release () cv2.destroyAllWindows ()
الرسم البياني للتدرجات الموجهة (HOG's)
الآن دعنا نتحدث عن واصف مختلف وهو الرسم البياني للتدرجات الموجهة (HOG's).
تعتبر HOG من الواصفات الرائعة والمفيدة إلى حد كبير ويتم استخدامها على نطاق واسع بنجاح لاكتشاف الكائنات ، كما رأينا سابقًا في واصفات الصور مثل SIFT و ORB حيث يتعين علينا حساب نقاط المفاتيح ومن ثم علينا حساب الواصفات من تلك النقاط الأساسية ، يقوم HOG بهذه العملية بشكل مختلف. إنه يمثل الكائنات كمتجه واحد للميزة بدلاً من مجموعة من متجهات الميزات حيث يمثل كل منها جزءًا من الصورة. هذا يعني أن لدينا ميزة متجه واحدة للصورة بأكملها.
يتم حسابه بواسطة كاشف نافذة انزلاقية فوق صورة ، حيث يتم حساب واصف HOG لكل موضع. ثم يتم دمج كل موضع في متجه ميزة واحد.
مثل SIFT ، يتم ضبط حجم الصورة عن طريق الهرمية.
في السابق استخدمنا المطابقات مثل FLANN و BFMatcher ، لكن HOGs تفعل ذلك بشكل مختلف بمساعدة مصنّفات SVM (آلة متجه الدعم) ، حيث يتم تغذية كل واصف HOG الذي يتم حسابه إلى مصنف SVM لتحديد ما إذا تم العثور على الكائن أم لا.
إليك الرابط إلى ورقة رائعة بقلم Dalal & Triggs حول استخدام HOGs لاكتشاف الإنسان:
الرسم البياني للتدرجات الموجهة (HOG's) ، خطوة بخطوة:
قد يكون فهم HOG أمرًا معقدًا للغاية ، ولكننا هنا سنتعامل فقط مع نظرية HOG دون التعمق في الرياضيات المتعلقة بها.
لنأخذ هذه الصورة قليلاً من البكسل ، وفي الزاوية العلوية يوجد مربع 8x8 بكسل هنا ، لذلك في هذا المربع نحسب متجه التدرج أو اتجاهات الحافة عند كل بكسل. يعني ذلك أننا في هذا المربع نحسب متجه التدرج اللوني للصورة للبكسل داخل المربع (فهي نوعًا من الاتجاه أو تدفق كثافة الصورة نفسها) ، وهذا يولد 64 متجهًا للتدرج (8 × 8) يتم تمثيلها بعد ذلك كمدرج تكراري. لذا تخيل مدرج تكراري يمثل كل متجه متدرج. لذا ، إذا كانت جميع النقاط أو الشدة تقع في اتجاه واحد ، لنفترض أن الرسم البياني لهذا الاتجاه 45 درجة ، فإن المدرج التكراري سيكون له ذروة عند 45 درجة.
ما نفعله الآن هو تقسيم كل خلية إلى صناديق زاوية ، حيث تتوافق كل سلة مع اتجاه التدرج اللوني (على سبيل المثال ، x ، y). في ورق Dalal و Triggs ، استخدموا 9 سلال 0-180 درجة (20 درجة لكل سلة) يؤدي هذا إلى تقليل 64 متجهًا إلى 9 قيم فقط. لذا فإن ما فعلناه هو تقليل الحجم ولكننا احتفظنا بجميع المعلومات الأساسية المطلوبة.
الخطوة التالية في حساب الخنازير هي التطبيع ، فنحن نطبيع التدرجات لضمان الثبات في تغيرات الإضاءة مثل السطوع والتباين.
في هذه الصورة ، تظهر قيم الشدة في المربع وفقًا للاتجاه المعني وكل منها لها فرق قدره 50 بين بعضها البعض
Δ H = 50، Δ ت = 50؛ │∆│ = 50 2 +50 = 70.72 ، 70.72 / 100 = 0.707
نقسم المتجهات على مقادير التدرج التي نحصل عليها 0.707 للجميع ، هذا هو التطبيع.
وبالمثل ، إذا قمنا بتغيير الكثافة أو تغيير التباين ، نحصل على القيم التالية.
Δ H = 50، Δ ت = 50؛ │∆│ = 50 2 +50 = 70.72 ، 70.72 / 100 = 0.707 ؛ Δ H = 100، Δ ت = 100؛ │∆│ = √100 2 +100 = 141.42 ، 141.42 / 100 = 1.41
لا يحدث التطبيع على مستوى الخلية ، بل يحدث على مستوى الكتلة ، لذا فإن الكتل هي في الأساس مجموعة من 4 خلايا ، وهذا يأخذ في الاعتبار الكتل المجاورة ، لذا يتم تطبيعها مع مراعاة الأجزاء الأكبر من الصورة.
الآن دعونا نلقي نظرة على الكود
استيراد numpy كـ np استيراد cv2 استيراد matplotlib.pyplot كـ plt # تحميل صورة ثم صورة بتدرج الرمادي = cv2.imread ('elephant.jpg') رمادي = cv2.cvtColor (صورة ، cv2.COLOR_BGR2GRAY) # إظهار الصورة الأصلية cv2.imshow (' صورة الإدخال '، صورة) cv2.waitKey (0) # تحديد المعلمات وحجم الخلية وحجم الكتلة # hxw بالبكسل cell_size = (8 ، 8) # hxw في الخلايا block_size = (2، 2) # عدد سلال التوجيه nbins = 9 # استخدام OpenCV's HOG Descriptor # winSize هو حجم الصورة التي تم اقتصاصها إلى مضاعف حجم الخلية hog = cv2.HOGDescriptor (_winSize = (gray.shape // cell_size * cell_size ، gray.shape // cell_size * cell_size)، _blockSize = (block_size * cell_size، block_size * cell_size)، _blockStride = (cell_size، cell_size)، _cellSize = (cell_size، cell_size)، _nbins = nbins) # نقوم بإنشاء شكل صفيف numpy لإنشاء hog_features n_cells = (gray.shape // cell_size، gray.shape // cell_size) # نقوم بفهرسة الكتل بالصفوف أولاً. # hog_feats تحتوي الآن على اتساع التدرج لكل اتجاه ، # لكل خلية من مجموعتها لكل مجموعة. تتم الفهرسة بالصفوف ثم الأعمدة. hog_feats = hog.compute (رمادي). reshape (n_cells - block_size + 1، n_cells - block_size + 1، block_size، block_size، nbins). تبديل ((1، 0، 2، 3، 4)) # أنشئ مصفوفة التدرجات الخاصة بنا بأبعاد nbin لتخزين تدرجات اتجاهات التدرج = np.zeros ((n_cells، n_cells، nbins)) # إنشاء مجموعة من الأبعاد cell_count = np.full ((n_cells، n_cells، 1)، 0، dtype = int) # تسوية الحظر لـ off_y في النطاق (block_size): لـ off_x في النطاق (block_size): التدرجات - block_size + off_y + 1، off_x: n_cells - block_size + off_x + 1] + = \ hog_feats cell_count - block_size + off_y + 1، off_x: n_cells - block_size + off_x + 1] + = 1 # متوسط التدرجات اللونية / = cell_count # مؤامرة HOGs باستخدام Matplotlib # زاوية هي 360 / nbins * direction color_bins = 5 plt.pcolor (التدرجات) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('يساوي' ، قابل للتعديل = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
توضح الصورة كيف يتم تمثيل صورة الإدخال كتمثيل HOG.
المصنفات المتتالية HAAR
كما تمت مناقشته سابقًا ، يمكننا استخراج ميزات من صورة ما واستخدام هذه الميزات لتصنيف الكائنات أو اكتشافها.
ما هي مصنفات HAAR Cascade؟
طريقة لاكتشاف الكائن تُدخل ميزات Haar في سلسلة من المصنفات (تتالي) لتحديد الكائنات في الصورة. إنهم مدربون على تحديد نوع واحد من الأشياء ، ومع ذلك ، يمكننا استخدام العديد منها بالتوازي ، مثل اكتشاف العيون والوجوه معًا.
وأوضح المصنفات HAAR:
يتم تدريب HAAR Classifiers باستخدام الكثير من الصور الإيجابية (أي الصور مع وجود الكائن)
والصور السلبية (أي الصور بدون وجود الكائن).
مرة واحدة لدينا تلك الصور، فإننا ثم استخراج الميزات باستخدام ويندوز انزلاق كتل مستطيلة. هذه الميزات (ميزات HAAR) ذات قيمة فردية ويتم حسابها عن طريق طرح مجموع شدة البكسل تحت المستطيلات البيضاء من المستطيلات السوداء.
ومع ذلك ، يعد هذا عددًا سخيفًا من الحسابات ، حتى بالنسبة لنافذة أساسية تبلغ 24 × 24 بكسل (تم إنشاء 180000 ميزة).
لذا ابتكر الباحثون طريقة تسمى Integral Images والتي قامت بحساب هذا باستخدام أربعة مراجع مصفوفة. ومع ذلك ، لا يزال لديهم 180،000 ميزة ولم يضيف معظمهم أي قيمة حقيقية.
تعزيز وتستخدم بعد ذلك لتحديد أهم سمات إعلامي مع فرويند وSchapire في AdaBoost وأنها وجدت ملامح أكبر قدر من المعلومات في الصورة. التعزيز هو العملية التي نستخدم بها المصنفات الضعيفة لبناء مصنفات قوية ، وذلك ببساطة عن طريق تعيين عقوبات أثقل ثقيلة على التصنيفات غير الصحيحة. تقليل 180.000 ميزة إلى 6000 ، والتي لا تزال ميزات قليلة جدًا.
في تلك الميزات 6000 ، سيكون بعضها أكثر إفادة من غيرها. لذا ، إذا استخدمنا الميزات الأكثر إفادة للتحقق أولاً مما إذا كان من المحتمل أن يكون للمنطقة وجه (الإيجابيات الخاطئة لن تكون مشكلة كبيرة). يؤدي القيام بذلك إلى التخلص من الحاجة إلى حساب كل ميزة 6000 مرة واحدة. يُطلق على هذا المفهوم اسم Cascade of Classifiers - للكشف عن الوجه ، استخدمت طريقة Viola Jones 38 مرحلة.
كشف الوجه والعين
لذلك بعد اكتساب بعض المعرفة النظرية حول شلالات HAAR ، سنقوم بتنفيذها أخيرًا ، لتوضيح الأمور إلى حد كبير ، سنقوم بتقسيم الدروس إلى أجزاء ، أولاً سنكتشف الوجه الأمامي بعد ذلك سننتقل لاكتشاف الوجه الأمامي باستخدام وأخيرًا سنقوم بالكشف المباشر للوجه والعينين من خلال كاميرا الويب.
لذلك ، سنستخدم المصنفات المدربة مسبقًا التي تم توفيرها بواسطة OpenCV كملفات.xml ، و xml تعني لغة الترميز الموسعة ، وتستخدم هذه اللغة لتخزين كمية هائلة من البيانات ، ويمكنك حتى بناء قاعدة بيانات عليها.
يمكنك الوصول إلى هذه المصنفات على هذا الرابط .
الكشف عن الوجه
دعنا نحاول الكشف عن الوجه الأمامي ، يمكنك الوصول إلى سلسلة كاشف الوجه الأمامي هنا. ما عليك سوى استخراج ملف zip للحصول على ملف xml.
import numpy كـ np import cv2 # نشير وظيفة CascadeClassifier الخاصة بـ OpenCV إلى المكان الذي يتم فيه تخزين المصنف # (تنسيق ملف XML) ، تذكر الاحتفاظ بالشفرة والمصنف في نفس المجلد face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # تحميل ثم تحول صورتنا إلى صورة ذات تدرج رمادي = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (image، cv2.COLOR_BGR2GRAY) # يُرجع المصنف العائد على الاستثمار للوجه المكتشف على هيئة مجموعة # يقوم بتخزين الجزء العلوي الأيسر التنسيق والإحداثيات اليمنى السفلية # تعيد قائمة القوائم ، وهي مواقع الوجوه المختلفة التي تم اكتشافها. الوجوه = face_cascade.detectMultiScale (رمادي ، 1.3 ، 5) # عندما لا يتم اكتشاف وجوه ، يعود face_classifier وتصفيف فارغة إذا كانت الوجوه (): print ("No faces found") # نحن نكرر عبر مصفوفة الوجوه الخاصة بنا ونرسم مستطيلًا # فوق كل وجه في الوجوه لـ (x ، y ، w ، ح) في الوجوه: cv2.rectangle (image، (x، y)، (x + w، y + h)، (127،0،255)، 2) cv2.imshow ('Face Detection'، image) cv2.waitKey (0) cv2.destroyAllWindows ()
الآن دعنا نجمع بين اكتشاف الوجه والعين معًا ، يمكنك الوصول إلى سلسلة كاشف العين في نفس الملف المضغوط.
استيراد numpy كـ np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') رمادي = cv2.cvtColor cv2.COLOR_BGR2GRAY) وجوه = face_classifier.detectMultiScale (رمادي ، 1.3 ، 5) # عند عدم اكتشاف أي وجوه ، يعود تصنيف الوجه ويخلف الصفوف إذا كانت الوجوه (): print ("No Face Found") لـ (x ، y ، w ، h) في الوجوه: cv2.rectangle (img، (x، y)، (x + w، y + h)، (127،0،255)، 2) cv2.imshow ('img'، img) roi_gray = gray roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) لـ (مثال ، ey ، ew ، eh) في العيون: cv2.rectangle (roi_color، (ex، ey)، (ex + ew، ey + eh)، (255،255،0)، 2) cv2.imshow ('img'، img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
إذن هذا الرمز هو نفسه رمز الكشف عن الوجه ، ولكن هنا أضفنا شلالات العين وطريقة اكتشافها ، كما ترون ، اخترنا النسخة المصغرة باللون الرمادي للوجه كمعامل لـ DiscoverMultiScale من أجل العيون ، وهو ما يقودنا إلى تقليل الحساب لأننا سنكتشف العيون فقط في تلك المنطقة فقط.
كشف مباشر للوجه والعين
لذلك حتى الآن قمنا باكتشاف الوجه والعين ، فلننفذ الأمر نفسه مع بث الفيديو المباشر من كاميرا الويب. في هذا ، سنفعل نفس الكشف عن الوجه والعينين ولكن هذه المرة سنفعل ذلك من أجل البث المباشر من كاميرا الويب. في معظم التطبيق ، ستجد وجهك مظللًا بمربع حوله ، ولكن هنا قمنا بشيء مختلف ستجد وجهك مقطوعًا وستحدد عينيك فيه فقط.
لذلك نحن هنا نستورد كلاً من مُصنف الوجه والعين ، وحددنا وظيفة للقيام بكل المعالجات لاكتشاف الوجه والعين. وبعد ذلك بدأ تدفق كاميرا الويب واستدعى وظيفة كاشف الوجه للتعرف على الوجه والعينين. المعلمة التي نحددها داخل وظيفة كاشف الوجه هي الصور المستمرة من بث كاميرا الويب الحية
استيراد cv2 استيراد numpy كـ np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img، size = 0.5): # رمادي تحويل الصورة إلى تدرج الرمادي (img، cv2.COLOR_BGR2GRAY) وجوه = face_classifier.detectMultiScale (رمادي ، 1.3 ، 5) إذا كانت الوجوه هي (): إرجاع img لـ (x ، y ، w ، h) في الوجوه: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2.rectangle (img، (x، y)، (x + w، y + h)، (255،0،0)، 2) roi_gray = رمادي roi_color = img العيون = eye_classifier.detectMultiScale (roi_gray) لـ (على سبيل المثال ، ey ، ew ، eh) في العيون: cv2.rectangle (roi_color، (ex، ey)، (ex + ew، ey + eh)، (0،0،255)، 2) roi_color = cv2.flip (roi_color، 1) return roi_color cap = cv2.VideoCapture (0) بينما صحيح: ret ، frame = cap.read () cv2.imshow ('Our Face Extractor' ، face_detector (frame)) إذا كان cv2.waitKey (1) == 13: # 13 هو إدخال غطاء كسر المفتاح. cv2.destroyAllWindows ()
ضبط المصنفات المتتالية
المعلمات المحددة داخل DiscoverMultiScale بخلاف صورة الإدخال لها الأهمية التالية
مصنفنا. DiscoverMultiScale (صورة الإدخال ، عامل المقياس ، الحد الأدنى من الجيران)
- Scale Factor يحدد مقدار تقليل حجم الصورة في كل مرة نقوم فيها بالقياس. على سبيل المثال ، في اكتشاف الوجه ، نستخدم عادةً 1.3. هذا يعني أننا نقوم بتصغير الصورة بنسبة 30٪ في كل مرة يتم قياسها. القيم الأصغر ، مثل 1.05 سوف تستغرق وقتًا أطول للحساب ، ولكنها ستزيد من معدل الاكتشاف.
- يحدد Min Neighbours عدد الجيران الذي يجب أن تمتلكه كل نافذة محتملة من أجل اعتباره اكتشافًا إيجابيًا. يتم تحديده عادة بين 3-6. إنه يعمل كإعداد للحساسية ، والقيم المنخفضة تكتشف أحيانًا الوجوه المتعددة على وجه واحد. ستضمن القيم العالية نتائج إيجابية أقل خطأ ، ولكن قد تفقد بعض الوجوه.
كشف السيارات والمشاة في مقاطع الفيديو
الآن سنكتشف المشاة والسيارات في مقاطع الفيديو باستخدام شلالات HAAR ، ولكن في حالة عدم تحميل أي فيديو وتجميع الكود بدون خطأ ، يجب اتباع الخطوات التالية:
إذا لم يتم تحميل أي فيديو بعد تشغيل الكود ، فقد تحتاج إلى نسخ opencv_ffmpeg.dl الخاص بنا من : opencv \ sources \ 3rdparty \ ffmpeg للصقه حيث تم تثبيت python الخاص بك ، على سبيل المثال C: \ Anaconda2
بمجرد نسخ الملف ، ستحتاج إلى إعادة تسمية الملف وفقًا لإصدار OpenCV الذي تستخدمه.eg إذا كنت تستخدم OpenCV 2.4.13 ثم أعد تسمية الملف باسم: opencv_ffmpeg2413_64.dll أو opencv_ffmpeg2413.dll (إذا كنت تستخدم OpenCV باستخدام جهاز X86) opencv_ffmpeg310_64.dll أو opencv_ffmpeg310.dll (إذا كنت تستخدم جهاز X86)
ل معرفة حيث تم تثبيت لك python.exe ، فقط تشغيل هذين الخطين من التعليمات البرمجية، فإنه طباعة الموقع حيث تم تثبيت الثعبان.
استيراد طباعة sys (sys.executable)
الآن إذا كنت قد نفذت هذه الخطوات بنجاح ، فلننتقل إلى رمز اكتشاف المشاة ،
يمكنك الحصول على تسلسل اكتشاف المشاة ومن الملف المضغوط المرفق هنا.
import cv2 import numpy as np # إنشاء مصنف الجسم body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # بدء التقاط الفيديو لملف الفيديو ، نحن هنا نستخدم ملف الفيديو الذي سيتم فيه اكتشاف المشاة cap = cv2.VideoCapture ('Walking.avi') # Loop بمجرد تحميل الفيديو بنجاح أثناء cap.isOpened (): # قراءة كل إطار من إطار ret ، frame = cap.read () # هنا نقوم بتغيير حجم الإطار ، إلى نصف حجمه ، نحن نعمل على تسريع التصنيف # حيث تحتوي الصور الأكبر على عدد أكبر من النوافذ لتنزلق عليها ، لذلك بشكل عام نقوم بتقليل الدقة # من الفيديو بمقدار النصف وهذا ما يشير إليه 0.5 ، ونستخدم أيضًا طريقة استيفاء أسرع وهي # إطار خطي = cv2.resize (إطار ، بلا ، fx = 0.5 ، fy = 0.5 ، الاستيفاء = cv2.INTER_LINEAR) رمادي = cv2. cvtColor (frame، cv2.COLOR_BGR2GRAY) # تمرير الإطار إلى أجسام مصنف الجسم لدينا = body_classifier.detectMultiScale (رمادي ، 1.2 ، 3) # استخراج المربعات المحيطة لأي هيئات تم تحديدها لـ (x ، y ، w ، h) في الأجسام: cv2. مستطيل (إطار ، (x ، y) ، (x + w ، y + h) ، (0 ، 255 ، 255) ، 2) cv2.imshow ('Pedestrians' ، frame) إذا كان cv2.waitKey (1) == 13: # 13 هو إدخال الحد الأقصى لكسر المفتاح. الإصدار () cv2.destroyAllWindows ()
بعد اكتشاف المشاة في الفيديو بنجاح ، دعنا ننتقل إلى رمز الكشف عن السيارة ، يمكنك الحصول على تسلسل اكتشاف المشاة من هنا.
استيراد cv2 استيراد وقت استيراد numpy كـ np # إنشاء مصنف الجسم car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # بدء التقاط الفيديو لغطاء ملف الفيديو = cv2.VideoCapture ('cars.avi') # Loop بمجرد نجاح الفيديو تم تحميله أثناء cap.isOpened (): time.sleep (.05) # قراءة الإطار الأول ret ، frame = cap.read () gray = cv2.cvtColor (frame، cv2.COLOR_BGR2GRAY) # تمرير الإطار إلى سياراتنا المُصنفة للسيارات = car_classifier.detectMultiScale (رمادي ، 1.4 ، 2) # استخراج المربعات المحيطة لأي أجسام محددة لـ (x ، y ، w ، h) في السيارات: cv2.rectangle (frame، (x، y)، (x + w، y + h)) ، (0 ، 255 ، 255) ، 2) cv2.imshow ('Cars' ، الإطار) إذا كان cv2.waitKey (1) == 13: # 13 هو إدخال الحد الأقصى لكسر المفتاح .release () cv2.destroyAllWindows ()
لقد لاحظت أننا أضفنا time.sleep (.05) ، إنه مجرد تأخير في معدل الإطارات حتى تتمكن من التأكد من تحديد جميع السيارات بشكل صحيح ، أو يمكنك إزالتها بسهولة فقط عن طريق إضافة تسمية تعليق إليها.
تمت إحالة هذه المقالة من Master Computer Vision ™ OpenCV4 في Python مع دورة التعلم العميق على Udemy ، التي أنشأها راجيف راتان ، واشترك فيها لمعرفة المزيد عن رؤية الكمبيوتر وبايثون.