بناء نظام التعرف على الوجوه على أساس Golang و OpenCV
OpenCV هي مكتبة مصممة لمشاريع رؤية الكمبيوتر. عمرها بالفعل حوالي 20 عامًا. لقد استخدمته في الكلية وما زلت أستخدمه في مشاريع C++ وPython الخاصة بي لأنه يتمتع بدعم جيد لتلك اللغات.
ولكن عندما بدأت تعلم لغة Go واستخدامها، أصبحت مهتمًا بمعرفة ما إذا كان من الممكن استخدام OpenCV للعمل مع هذه اللغة. في ذلك الوقت، كانت هناك بالفعل أمثلة ودروس تعليمية حول التكامل، ولكن بدا لي أنها معقدة للغاية. وبعد فترة وجيزة، صادفت غلافًا أنشأه فريق Hybrid Group. سأوضح لك في هذه المقالة كيفية البدء في استخدام GoCV من خلال تطوير نظام بسيط للتعرف على الوجوه باستخدام Haar Cascades.
في المثال الأول، سنحاول إنشاء تطبيق يفتح نافذة تعرض دفق فيديو الكاميرا.
تحتاج أولاً إلى استيراد المكتبات اللازمة للعمل.
يستورد (
"سجل"
"gocv.io/x/gocv"
)
بعد ذلك، تحتاج إلى إنشاء كائن VideoCapture باستخدام وظيفة VideoCaptureDevice. هذا الأخير يجعل من الممكن التقاط دفق الفيديو باستخدام الكاميرا. تستخدم الدالة عددًا صحيحًا كمعلمة (يمثل معرف الجهاز).
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil { log.Fatalf(“error opening web cam: %v”, err)
}
defer webcam.Close()
الآن نحن بحاجة إلى إنشاء مصفوفة ذات أبعاد n. سيتم تخزين الصور المقروءة من الكاميرا.
img := gocv.NewMat()
defer img.Close()
لعرض دفق الفيديو، تحتاج إلى إنشاء نافذة - يمكن القيام بذلك باستخدام وظيفة NewWindow.
نظرًا لأن الفيديو عبارة عن دفق مستمر من إطارات الصور، فسنحتاج إلى إنشاء حلقة لا نهائية لقراءة دفق الفيديو الخاص بالكاميرا إلى ما لا نهاية. للقيام بذلك، تحتاج إلى طريقة القراءة من نوع VideoCapture. سيتوقع نوع Mat (المصفوفة التي أنشأناها أعلاه)، مما يعيد قيمة منطقية تشير إلى ما إذا كان الإطار من VideoCapture قد تمت قراءته بنجاح أم لا.
for {
if ok := webcam.Read(&img); !ok || img.Empty( {
log.Println(“Unable to read from the webcam”) continue
}
.
.
.
}
أنت الآن بحاجة إلى عرض الإطار في النافذة التي تم إنشاؤها. فترة التوقف للانتقال إلى الإطار التالي هي 50 مللي ثانية.
نافذة.IMShow(img)
نافذة.انتظار المفتاح(50)
بعد تشغيل التطبيق، سيتم فتح نافذة بها دفق فيديو من الكاميرا.
package main
import (
"log"
"gocv.io/x/gocv"
)
func main() {
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
log.Fatalf("error opening device: %v", err)
}
defer webcam.Close()
img := gocv.NewMat()
defer img.Close()
window := gocv.NewWindow("webcamwindow")
defer window.Close()
for {
if ok := webcam.Read(&img); !ok || img.Empty() {
log.Println("Unable to read from the webcam")
continue
}
window.IMShow(img)
window.WaitKey(50)
}
}
مثال 2
في هذا المثال، دعونا نستخدم المثال السابق ونبني نظام التعرف على الوجوه استنادًا إلى Haar Cascades.
شلالات هار هي مصنفات متتالية يتم تدريبها باستخدام تقنية مويجات هار. يقومون بتحليل وحدات البكسل في الصورة لاكتشاف ميزات معينة. لمعرفة المزيد عن Haar Cascades، يرجى اتباع الروابط أدناه.
قم بتنزيل الشلالات المدربة بالفعل هنا. في المثال الحالي، سيتم استخدام التتاليات للتعرف على وجه الشخص من الأمام.
للقيام بذلك، تحتاج إلى إنشاء مصنف وإطعامه بملف تم تدريبه بالفعل (الرابط موجود أعلاه). لقد قمت بالفعل بتحميل ملف pencv_haarcascade_frontalface_default.xml إلى الدليل الذي يوجد به برنامجنا.
لاكتشاف الوجوه في صورة ما، تحتاج إلى استخدام هذه الطريقة DetectMultiScale. تأخذ هذه الوظيفة إطارًا (من النوع Mat) تمت قراءته للتو من دفق الفيديو الخاص بالكاميرا وتقوم بإرجاع مصفوفة من النوع Rectangle. يمثل حجم المصفوفة عدد الوجوه التي تمكن المصنف من اكتشافها في الإطار. بعد ذلك، للتأكد من أننا رأينا ما تم العثور عليه، دعنا نكرر قائمة المستطيلات ونطبع كائن المستطيل على وحدة التحكم، مما يؤدي إلى إنشاء حد حول المستطيل الذي تم اكتشافه. يمكن القيام بذلك باستخدام وظيفة المستطيل. سيقبل حصيرة القراءة بواسطة الكاميرا، وكائن المستطيل الذي تم إرجاعه بواسطة طريقة DetectMultiScale، ولون الحدود وسمكها.
for _, r := range rects {
fmt.Println(“detected”, r)
gocv.Rectangle(&img, r, color, 2)
}
package main
import (
"fmt"
"image/color"
"log"
"gocv.io/x/gocv"
)
func main() {
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
log.Fatalf("error opening web cam: %v", err)
}
defer webcam.Close()
img := gocv.NewMat()
defer img.Close()
window := gocv.NewWindow("webcamwindow")
defer window.Close()
harrcascade := "opencv_haarcascade_frontalface_default.xml"
classifier := gocv.NewCascadeClassifier()
classifier.Load(harrcascade)
defer classifier.Close()
color := color.RGBA{0, 255, 0, 0}
for {
if ok := webcam.Read(&img); !ok || img.Empty() {
log.Println("Unable to read from the device")
continue
}
rects := classifier.DetectMultiScale(img)
for _, r := range rects {
fmt.Println("detected", r)
gocv.Rectangle(&img, r, color, 3)
}
window.IMShow(img)
window.WaitKey(50)
}
}
و... نعم، كل شيء على ما يرام! لدينا الآن نظام بسيط للتعرف على الوجه مكتوب بلغة Go. أخطط قريبًا لمواصلة هذه التجارب وإنشاء أشياء رائعة جديدة من خلال الجمع بين Go وOpenCV.
إذا كنت مهتما، يرجى معدل خادم الويب gRPCالتي كتبتها في بايثون وOpenCV. يقوم بتدفق البيانات لحظة اكتشاف الوجه. هذا هو الأساس لإنشاء عملاء مختلفين بلغات برمجة مختلفة. سيكونون قادرين على الاتصال بالخادم وقراءة البيانات منه.