تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
مقارنة صورتين و الحصول علي الفرق بينهم Comparing Two Images and Get Diff Image
#1
مقدمة:

هذا الموضوع سوف يوضح كيفية المقارنة بين صورتين و الحصول علي صورة ثالثة توضح الفارق بين الصورتين
عامل السرعة في المقارنة بين الصور أمر هام جدا و أغلب الموضوعات علي النت لم تضع في اعتبارها سرعة تنفيذ الكود
أيضا أغلب الموضوعات علي النت عتمدت علي استخدام Bitmap.GetPixel وتستخدمها لكي تقارن بين الألوان في الصورتين و هذا بالطبع يؤدي الي بطء في الاداء و غالبا لا يعطي نتائج مرضية للمبرمج

لضمان عامل السرعة في تنفيذ الكود سوف استخدم Bitmap.LockBits و Marshal Class للحصول علي مصفوفة Byte الحاصة بألوان الصورة
يجب الوضع في الاعتبار لو ان الصور المستخدمة في المقارنة ابعادها مختلفة فهنا تصبح المقارنة بلا جدوي

قد يتساءل البعض منكم و ما فائدة مثل هذا الموضوع
وإجابة هذا السؤال تتلخص في التالي
الفكرة المستخدمة هنا مفيدة جدا في مقارنة التغييرات في الصور و هي تستخدم غالبا في كاميرات المراقبة  و أشياء أخري من هذا القبيل
وهناك شركات كثيرة عملها مبني علي الفكرة التي سوف نناقشها هنا لذلك قليلا ما تجد أحد يرد علي اسئلة مشابهة لأن الأمر و ببساطة شديدة عبارة عن بيزنس
وغالبا لن تجد أحد من المبرمجين يكشف أسرار عمله لمبرمج أخر
عموما كيفية الاستفادة من الكود متروك لمخيلة القارئ و غالبا ستجدون له استخدامات كثيرة

الفكرة:
المراحل التالية توضح خطوات العمل

المرحلة الأولي:
يكون لديك صورتان متشابهتان لكن بينهما فارق بسيط
و هنا انا حصلت علي الصور التي سأستخدمها في المقارنة من موضوع مشابه و لكنه مكتوب بلغة Ruby علي ما أتذكر
وحتي الموضوع الذي أخذت منه الصور يعتمد في المقارنة بين الصور علي فكرة مقارنة الألوان الموجودة في الصور باستخدام Bitmap.GetPixel

المرحلة الثانية:
بعد الحصول علي الصور نقوم بالحصول علي مصفوفة الألوان الخاصة بكل صورة
وبمجرد أن تفعل هذا فأنت تقريبا تكون إنتهيت من نصف العمل تقريبا

المرحلة الثالثة:
بعد الحصول علي مصفوفة الألوان الخاصة بكل صورة نقوم بتعريف متغير عبارة عن مصفوفة ثالثة تكون السعة الخاصة بها مساوية لأي من المصفوفتان الخاصة بالصور
هذه المصفوفة ستعمل بمثابة مصفوفة الألوان للصورة التي تبين الفارق بين الصورتان و لنطلق عليها مصفوفة الفروقات

المرحلة الرابعة:
بعد ذلك نقوم بعمل حلقة تكرارية و نقارن بين الألوان أو بين ARGB الخاصة بكل بكسل في مصفوفات الصور
فإن كانت الألوان مماثلة نقوم بملئ المصفوفة الثالثة وهي مصفوفة الفروقات بلون بديل وليكن اللون Magenta مثلا
و ان كانت الألوان في مصفوفات الصور مختلفة نقوم بإضافة اللون المختلف الي المصفوفة الثالثة وهي مصفوفة الفروقات
أعلم جيدا ان المرحلة هذه ربما لا تكون غير واضحة للبعض منكم لكني أثق تماما انه عند تنفبذها برمجيا ستتضح لكم
عند الانتهاء من هذه المرحلة تكون فعليا انتهيت بنسبة 90 في المائة من العمل

المرحلة الخامسة و الأخيرة:
ناخذ مصفوفة الفروقات و نحولها الي صورة

الكود:

الكود التالي يوضح الفكرة مع شرح تفصيلي

PHP كود :
       ' المرحلة الأولي

        ' 
تعريف الصورتان المراد المقارنة بينهما و الحصول منهما علي صورة توضح الفارق بين الصورتان
        Dim sourceBitmap 
As Bitmap PictureBox2.Image
        Dim destBitmap 
As Bitmap PictureBox1.Image


        
' المرحلة الثانية 

        ' 
الحصول علي مصفوفة البايت الخاصة بكل صورة أعلاه

        
' الحصول علي مصفوفة الأوان الخاصة بالصورة الأولي و هي عبارة عن مصفوفة بايت

        Dim sourceBitmapData As Imaging.BitmapData = sourceBitmap.LockBits(New Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)
        Dim sourceBytes As Byte() = New Byte(sourceBitmapData.Stride * sourceBitmapData.Height - 1) {}
        Runtime.InteropServices.Marshal.Copy(sourceBitmapData.Scan0, SourceBytes, 0, SourceBytes.Length)
        sourceBitmap.UnlockBits(sourceBitmapData)

        ' 
الحصول علي مصفوفة الأوان الخاصة بالصورة الثانية و هي أيضا عبارة عن مصفوفة بايت

        Dim destBitmapData 
As Imaging.BitmapData destBitmap.LockBits(New Rectangle(00destBitmap.WidthdestBitmap.Height), Imaging.ImageLockMode.ReadOnlyImaging.PixelFormat.Format32bppArgb)
 
       Dim destBytes As Byte() = New Byte(destBitmapData.Stride destBitmapData.Height 1) {}
 
       Runtime.InteropServices.Marshal.Copy(destBitmapData.Scan0destBytes0destBytes.Length)

 
       destBitmap.UnlockBits(destBitmapData)

 
       ' المرحلة الثالثة

        ' 
تعريف متغير يعبر عن مصفوفة الفروقات في الألوان
        
' وهذا المتغير عبارة عن مصفوفة بايت و السعة الخاصة بهذه المصفوفة تكون بنفس سعة اي من مصفوفات الصور أعلاه

        Dim diffBytes As Byte() = New Byte(sourceBytes.Length - 1) {}


        ' 
المرحلة الرابعة
        
' بناء الحلقة التكرارية التي نقارن فيها بين الألوان في الصور

        ' 
ملحوظة هامة
        
' الألوان في الصور يتم تخزينها في صورة
        ' 
RGBARED Green Blue Alpha

        Dim i 
As Integer 0
        While i 
sourceBytes.Length 1
            
' نحصل علي اللون من الصورة الأولي و نقارنه باللون في الصورة الثانية
            ' 
يجب أن لا  ننسي أن الألوان في الصور علي هيئة 
            
' RGBA: RED Green Blue Alpha
            If (sourceBytes(i) = destBytes(i)) AndAlso (sourceBytes(i + 1) = destBytes(i + 1)) AndAlso (sourceBytes(i + 2) = destBytes(i + 2)) AndAlso (sourceBytes(i + 3) = destBytes(i + 3)) Then
                ' 
تعريف لون بديل سنستخدمه لنملأ به مصفوفة الفروقات في حالة تساوي الأوان في الصورتان
                Dim clr 
As Color Color.Magenta
                
' في حالة تساوي الوان البكسل في الصورتان نعبئ مصفوفة الفروقات بأي لون نحدده
                ' 
وهنا أنا اخترت اللون الماجنتا كلون بديل
                diffBytes
(i) = CByte(clr.R)
 
               diffBytes(1) = CByte(clr.G)
 
               diffBytes(2) = CByte(clr.B)
 
               diffBytes(3) = CByte(clr.A)

 
           Else
                
'  في حالة اختلاف الالون بين الصورتان
                ' 
نقوم بتعبئة مصفوفة الفروقات باللون الموجود في الصورة الأصلية

                diffBytes
(i) = sourceBytes(i)
 
               diffBytes(1) = sourceBytes(1)
 
               diffBytes(2) = sourceBytes(2)
 
               diffBytes(3) = sourceBytes(3)

 
           End If

 
           i += 4
        End 
While


 
       ' المرحلة الخامسة و الأخيرة 
        ' 
تحويل مصفوفة الفروقات الي صورة
        
' وهي تكون صورة نبنيها بنفس ابعاد اي من الصورتان التي نقارن بينهما

        Dim diffBitmp As New Bitmap(sourceBitmap.Width, sourceBitmap.Height)
        Dim data As Imaging.BitmapData = diffBitmp.LockBits(New Rectangle(0, 0, diffBitmp.Width, diffBitmp.Height), Imaging.ImageLockMode.WriteOnly, Imaging.PixelFormat.Format32bppArgb)
        ' 
نكتب مصفوفة الأوان باستخدام المارشال كلاس
        Runtime
.InteropServices.Marshal.Copy(diffBytes0data.Scan0diffBytes.Length)
 
       diffBitmp.UnlockBits(data)

 
       ' أخيرا نقوم بعرض صورة الفروقات في بكتشر بوكس
        Me.PictureBox3.Image = diffBitmp 


حاول تعكس السطران التاليان من الكود
PHP كود :
       Dim sourceBitmap As Bitmap PictureBox2.Image
        Dim destBitmap 
As Bitmap PictureBox1.Image 
بحيث تجعلهما هكذا و شاهد ما سيحدث


PHP كود :
       Dim sourceBitmap As Bitmap PictureBox1.Image
        Dim destBitmap 
As Bitmap PictureBox2.Image 



أتمني إن الكود يكون مفيدا للبعض منكم

تقبلوا تحياتي


الملفات المرفقة
.rar   Test_ImageDifferences.rar (الحجم : 568.91 ك ب / التحميلات : 356)
الرد }}}


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  التعامل مع الصور Images في بيئة الدوت نت باستخدام +GDI - مقدمة RaggiTech 3 5,858 30-07-21, 05:14 PM
آخر رد: kebboud
  الفرق بين تاريخين بدقه وبدون مشاكل (عدد الايام ممتاز) ali.alfoly 1 2,170 17-12-18, 07:39 PM
آخر رد: elgokr
  Compare Images المقارنة بين الصور Abu Ehab 0 3,269 31-10-18, 04:27 PM
آخر رد: Abu Ehab
  الفرق بين الأصناف Classes و الكائنات Objects RaggiTech 1 8,069 28-03-18, 10:30 PM
آخر رد: alsouf
  [VB.NET] ارجو المساعدة : How to Split an Image into Chunks amna jamal 2 2,156 23-01-18, 05:05 AM
آخر رد: silverlight
  مقارنة الكلمات و الأسماء العربية برمجيا silverlight 4 4,015 20-12-15, 08:34 PM
آخر رد: silverlight
  Create, Save Tiff Image & Extract Images From TIFF Image silverlight 0 2,621 09-10-15, 01:40 PM
آخر رد: silverlight
  [مقال] Check the file format of an Image silverlight 3 3,375 28-05-14, 05:02 PM
آخر رد: Sajad
  مقال- أفكار في الدوت نت Image To ColorPicker RaggiTech 3 2,849 05-10-12, 06:48 PM
آخر رد: RaggiTech
  للتحويل من Image إلى ByteArray والعكس - مع ملاحظة الطريقتين (ToArray - .GetBuffer.) RaggiTech 0 2,962 05-10-12, 02:07 AM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم