السبت، 27 أبريل 2013

vb.net and emgu Face Detection اكتشاف الوجوه

مقدمة

توجد كثير من التقنيات يمكن استخدامها بلغة Vb.net بكل سهولة  لكشف الوجوه Face Detection  منها   تقنية Code التي توفرها شركة Google التي موجودة على الرابط التالي
والثانية تقنية OpenCV's توفرها شركة emgu  التي تعتمد على نظرية Viola-Jones method  في تحديد واستكشاف الوجوه في الصورة  موجودة على الرابط التالي  نقوم بتحميل المكتبة من الموقع



Face Detection Example



 كيف تستكشف الوجوه بنظرية Viola-Jones
سيكون شرحنا على طريقة عمل  تقنية OpenCV's  التي توفرها شركة emgu  لأننا سنبرمج باستخدام هذه التقنية.     تقنية OpenCV's تعتمد على نظرية Viola-Jones method في استكشاف الوجوه  .   تم اكتشاف هذا النظرية عام 2001 وهذا النظرية تستكشف  كل الأجزاء objects الموجودة في الصورة  ومنها أجزاء الوجه ونحن نجمع أجزاء الوجه لنكون وجه شخص وتلخص في أربع نقاط :
1.    مستطيل بسيط يسمى Haar features
2.    عمل تكامل الصورة لسرعة اكتشاف الأشكال أو الوجوه
3.    استخدام نظرية AdaBoost machine-learning
4.    عمل تجميع لأجزاء الوجه (انف عيون فم) لتكون صورة باستخدام cascaded classifier

نظرية Viola-Jones method تعتمد على  تحويل Haar wavelets في استكشاف الصور                
Haar wavelets هو موجة واحدة مربعة (جزء واحد عالي وجزء واحد واطئ ). في ثنائية الإبعاد هو موجة مربعة مكونة من أزواج من المستطيلات المتجاورة  كل واحدة  لونين اسود وابيض كما في Figure 1
          


Figure 1


معدل Haar   في كل مستطيل  يحسب بطرح مجموع قيم pixel في مناطق سوداء من مجموع قيم pixel في مناطق بيضاء وتقسيمها على مجموع pixel في المنطقتين إذا كان نتيجة الاختلاف اعلي من a threshold  الذي يحدد خلال  نظرية machine-learning يعتبر هذا الجزء هو جزء من الوجه ويتجه ليبحث عن بقية الأجزاء الخاصة بالوجه ضمن نفس المربع بتطبيق
مستطيلات Haar   على بقية pixel  شاهد Figure 4. عن طريق استخدام تكامل integrating يعني جمع أجزاء الصغيرة مع بعض في هذه الحالة الأجزاء الصغيرة هي قيم  pixel .قيم integral لكل pixel هي مجموع كل pixel التي تقع فوقه . أي في Figure 2. قيمة pixel في موقع 4 هي مجموع (A+B+C+D) قيمة pixel في موقع3 هي (A+C) قيمة pixel في موقع 2 هي (ِ A+B) قيمة pixel في الموقع 1 في (A)
وتلخص العملية في هذه المعادلة
integer operations: (x4, y4) - (x2, y2) - (x3, y3) + (x1, y1). 

Figure 2
 


يبدأ بتحريك المربع البحث (الذي يحتوي في داخله على مستطيلات Haar)  من الجزء الأعلى الأيسر  في الصورة وينفذ مستطيلات Haar على كل Pixel الموجودة في المربع باحثا عن وجه الشخص  وبعدها يتحرك المربع إلى اليمين ويستمر إلى أن يصل إلى نهاية الجزء الأيمن  وبعدها يتحرك  المربع إلى الأسفل ويستمر سطر سطر وبعد أن ينتهي من دورة واحدة على كل الصورة بمربع ذو حجم معين يكبر حجم المربع ويعيد البحث في كل الصورة من جديد ويستمر يكبر المربع وينفذ مستطيلات Haar على كل Pixel الموجودة في المربع  حتى أخر مرة يكون المربع مساوي لحجم الصورة حتى يساعده في اكتشاف جميع الوجوه في الصورة مهما اختلف كبر رأس الشخص



Figure 4



شرح استخدام مكاتب  emgu  بلغة VB.Net  في اكتشاف الوجوه Face Detection

بالبداية ندخل على الربط التالي  نحمل النسخة التي تلاءم نظامنا حسب نوع نظام التشغيل الخاص بنا



 

إنا هنا اختارت الإصدار  2.4.0.1717 الخاصة بالمعالج ذو 32 bit لان نظامي هكذا.؟؟وسأشرح على  النسخة 2.4.0.1717 نقوم بتحميل النسخة من الموقع..؟
بعد التحميل نقوم بتنصيبها في الحاسوب على المسار الذي نريده؟ هنا نصبناها  على قرص \:F 

 





سيكون مسار للمجلد  الخاص بالمكتبة  Emgucv  بالشكل التالي
F:\emgucv-windows-x86 2.4.0.1717\



 

أكثر مجلدين سنستخدمهم هما مجلد bin ومجلد opencv



ألان نكون مشروع VB.NET جديد فيه نافذتين كما في الشكل  كل وحدة مصممة وفيها أدوات حسب الشكل؟


 

يوجد نوعين من الأنظمة  نظام bit=X86 ) 32(  ونظام bit=X64)  64   ( نستطيع معرفة نوع نظامنا بالضغط بزر Mouse الأيمن على My Computer واختيار خصائص  سيعرض لنا نوع نظام التشغيل الخاص بنا؟؟ لتحديد النظام الذي سيعمل عليه البرنامج  نصممه نذهب إلى التبويب التالي
(My Project--Compile-- Advanced Compile Options--Target CPU)
  


نضغط على Add reference  ونضيف المكاتب التالية Emgu.CV  , Emgu.Util   او كل مكاتب  Emgucv  
حتى لا نواجه مشكلة الموجودة في مجلد ( F:\emgucv-windows-x86 2.4.0.1717\bin )










نذهب داخل مجلد emgucv-windows-x86 2.4.0.1717
اذا كان نظام تشغيلنا 32 bit   نذهب الى المسار التالي
F:\emgucv-windows-x86 2.4.0.1717\bin\x86
اذا كان نظام تشغيلنا 64 bit    نذهب الى المسار التالي
F:\emgucv-windows-x86 2.4.0.1717\bin\x64




 

وننسخ جميع ملفات DLL التي تبدأ بأسم    opencv أو جميعها حتى لا نواجه مشكلة أما إلى المسار الذي يعمل منه البرنامج أي مجلد bin\Debug آو  إلى المسار C:\Windows\System32







كود البرنامج كامل الذي سيكتب في Form1
VB.net Code
Imports Emgu.CV
Imports Emgu.CV.Structure
Imports Emgu.Util
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Drawing
Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
OpenFileDialog1.ShowDialog()


'Load the image from file
Dim img As New Image(Of Bgr, Byte)(OpenFileDialog1.FileName)

'Load the object detector
Dim faceDetector As New HaarCascade("F:\emgucv-windows-x86 2.4.0.1717\opencv\data\haarcascades\haarcascade_frontalface_default.xml")

'Convert the image to Grayscale
Dim imgGray As Image(Of Gray, Byte) = img.Convert(Of Gray, Byte)()

For Each face As MCvAvgComp In faceDetector.Detect( _
imgGray, _
1.1, _
10, _
CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, _
New Size(20, 20), _
Size.Empty)
img.Draw(face.rect, New Bgr(Color.White), 1)
Next

Form2.Show()
Form2.PictureBox1.Image = img.Bitmap


End Sub
End Class





شرح كود اكتشاف الوجود خطوة بخطوة

1.     نستدعي المكاتب التالية من مكتبة   Emgu بعد أن نضيفها إلى المشروع عن طريق Add Reference
VB.net Code
Imports Emgu.CV
Imports Emgu.CV.Structure
Imports Emgu.Util

وقد نحتاج إلى المكاتب التالية يفضل أضافتها حتى لا نواجه مشاكل في الرسم
VB.net Code
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Drawing

2.     نقرئ الصورة التي نريد تحديد الوجوه فيها  من المسار المخزنة به ونخزنها داخل متغير img  من نوع صورة؟هنا قرئنا صورة مخزنة داخل  المسار
  C:\test.jpg

VB.net Code
Dim img As New Image(Of Bgr, Byte)("C:\test.jpg")

3.    نقرئ الملف haarcascade_frontalface_default.xml الموجود بالمسار
F:\emgucv-windows-x86 2.4.0.1717\opencv\data\haarcascades
وهذا الملف متخصص في تجميع ملامح الوجه  HaarCascade وتكوين وجه للشخص لتحديده شاهد Figure 3

VB.net Code
Dim faceDetector As New HaarCascade("F:\emgucv-windows-x86 2.4.0.1717\opencv\data\haarcascades\haarcascade_frontalface_default.xml")

4.     نحول الصورة التي قرئناها إلى صورة ابيض واسود Gray لان إجراء البحث Detect الموجود في HaarCascade يأخذ الصورة بصيغة Gray
VB.net Code
Dim imgGray As Image(Of Gray, Byte) = img.Convert(Of Gray, Byte)()

5.     نبحث عن كل وجه ضمن الصورة ونضع مستطيل حول الوجه
VB.net Code
For Each face As MCvAvgComp In faceDetector.Detect(imgGray, 1.1, 10, CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, New Size(20, 20),Size.Empty)
img.Draw(face.rect, New Bgr(Color.White), 1)
Next

يعيد إجراء  Detect بيانات وجه بشكل MCvAvgComp توضيح برامترات إجراء Detect
Construct
Detec ( _
        haarObj As HaarCascade, _
        scaleFactor As Double, _
        minNeighbors As Integer, _
        flag As HAAR_DETECTION_TYPE, _
        minSize As Size _
) As MCvAvgComp()()


الوظيفة
البرامتر
هي الصورة التي نريد تحديد الوجوه فيها  بعد تحويلها  الى Gray
haarObj
تمثل Factor الذي نستخدمه Windows في تحديد فترة البحث بين بحثين متتاليين مثلا 1.1 يمثل زيادة بحث Windows  بمقدار  %10
scaleFactor
اصغر رقم للمستطيل المجاور الذي يمثل كل وجه  إذا كان يساوي صفر فان الدالة لا تجمع الإشكال وتعيد كل جزء object بشكل مستطيل منفصل
minNeighbors
تستخدم في إهمال أطراف بعض الصور التي تحتوي على قليل أو كثير من الأطراف التي لا تحتوي على object للبحث
flag
    اصغر حجم  Windows بشكل تلقائي يجعل حجم Samples هو 20*20
minSize





يأخذ إجراء Draw ثلاث برامترات
Construct
img.Draw(face.rect, New Bgr(Color.White), 1)
        §            البرامتر الأول الوجه الذي نريد تخطيطه
        §            البرامتر  الثاني  لون الخط الذي سنرسم به مستطيل حول الوجه
        §            البرامتر الثالث هو سمك الخط أو سمك أطراف المستطيل الذي سيغطي كل وجه

6.     الآن تم تحديد كل الوجوه في الصورة بقي فقط نستعرض الصورة ويفضل استعراضها على نافذة ثانية ندرج فيها أداة Picturebox وتستعرض بالشكل التالي
VB.net Code
Form2.Show()
Form2.PictureBox1.Image = img.Bitmap

وإذا أردنا أيضا تحديد عيون الأشخاص في الصور فقط نستدعي الملف haarcascade_eye.xml الخاص بمعالج عيون الأشخاص في الصور الصور الموجود في المسار  التالي
F:\emgucv-windows-x86 2.4.0.1717\opencv\data\haarcascades\
ونضيف هذا الكود

VB.net Code
'Load the object detector
Dim faceDetector1 As New HaarCascade("F:\emgucv-windows-x86 2.4.0.1717\opencv\data\haarcascades\haarcascade_eye.xml")

For Each face As MCvAvgComp In faceDetector1.Detect(imgGray, 1.1, 10, CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, New Size(20, 20), Size.Empty)
img.Draw(face.rect, New Bgr(Color.Red), 2)
Next
 














حمل المثال من هنا