اهلا بك اخ sharp7 و انصحك ان تبدا من اليوم .
اخ jarour : لم افهم سؤالك بالضبط :confused:
اهلا بك اخ sharp7 و انصحك ان تبدا من اليوم .
اخ jarour : لم افهم سؤالك بالضبط :confused:
مقدمة في معالجة الصور
الصورة عبارة عن مصفوفة مكونة من قيم الوانها (احمر, ازرق, اخضر) . و كل قيمة من هذه القيم ترسم في نقطة تسمى بكسل Pixel في اداة PictureBox .
و بالتالي اذا اردنا ان نقوم بتغييرات بالصور او ان نقوم بعمل فلتر Filter فما علينا الا ان نقوم بتغيير هذه القيم .
فمثلا اذا اردنا ان نقوم بعكس الوان الصورة Inverse فعلينا ان نقوم بطرح كل لون من الوان الصورة من 255 . فمثلا اذا كانت هناك صورة زرقاء بالكامل (0 , 255 , 0 ) فان المعكوس سيصبح (255 , 0 , 255 ) .
و اذا اردت تمليس الصورة Blur فان العملية اصعب قليلا و لكنها فكرة ذكية جدا .
الفكرة هي ان تجعل الوان الصورة قريبة من بعضها . ولكي تقوم بذلك فعليك باخذ المتوسط من كل 9 نقاط Pixels في الصورة . فاذا كانت هناك نقطة ذات فرق كبير في درجة لونها عن الثمانية النقاط الاخر فان المتوسط سوف يقرب لون هذه النقطة من الوان اخواتها الثمانية .
و كذلك شحذ او تحديد الصور Sharpen فما عليك الا القيام بعكس عملية التمليس .
كما ان هناك عمليات اخرى كثيرة ولكن المهم ان نفهم المبدا وهو انك سوف تتعامل مع الوان الصورة .
و بطبيعة الحال فان فجوال بيسك .نت يدعم هذا النوع من العمليات بدالتين هما GetPixel و SetPixel . اما الاولى فهي للحصول على الوان الصورة , واما الثانية فهي للتعديل في الوان الصورة .
يبقى علينا التطبيق برمجيا بعد الانتهاء من فهم الفكرة نظريا .
عكس الوان الصور
اتبع الخطوات الاتية:
1- ابدا مشروع ويندوز , ثم اضف زر امر و مربع صورة , ثم اضف صورة من عندك الى مربع الصورة .
2- اكتب هذا الكود تحت زر الامر :
Dim bmap As New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim red, green, blue As Integer Dim i, j As Integer With bmap For i = 1 To .Height - 2 For j = 1 To .Width - 2 red = CInt(.GetPixel(j, i).R) blue = CInt(.GetPixel(j, i).B) green = CInt(.GetPixel(j, i).G) bmap.SetPixel(j, i, Color.FromArgb(255 - red, 255 - green, 255 - blue)) Next PictureBox1.Refresh() Next PictureBox1.Refresh() End With
ساقوم بشرح النقاط الاساسية في هذا الكود .
في بداية الامر قمنا بانشاء متغير و خزنّا فيه الصورة الموجودة في مربع الصورة .
بعد ذلك انشأنا حلقتي تكرار . الاول يقوم بفحص عدد صفوف البكسل الموجودة في الصورة . و الثاني يقوم بفحص كل بنقطة او بكسل موجودة في الصورة .
ثم قمنا بتجميع النقاط ذات اللون الازرق و تخزينها في المتغير blue . و كذلك اللون الاحمر و الازرق . وذلك عن طريق الدالة GetPixels و التي لها تابعين و هما احداثي النقطة التي تريدها x ,y .
ثم استخدمنا الدالة SetPixel للقيام بعكس الوان الصورة , و التي لها 3 توابع :
الاول و الثاني هما احداثي النقطة التي تريد تغيير لونها .
الثالث : اللون الذي تريده للنقطة . و كما تلاحظ فاننا طرحنا كل لون من 255 لنقوم بعكس الوان الصورة .
و اذا اردت تسريع العملية فقم بحذف
PictureBox1.Refresh()
الاولى لانها تحت عملية التكرار الاولى . ووظيفتها انها تجعلك ترى العملية .
و إن شاء الله سوف نتعلم فكرة تمليس الصورة في الدرس القادم و هي فكرة رائعة جدا جدا .
ارجو ان الدرس كان ممتعا . و انتظر تعليقاتكم
تحياتــــــــــــــــــــــــــــــي .
تمليس الصور
الفكرة كما ذكرت سابقا عبارة عن تقريب درجة الوان النقاط من بعضها . فاذا كانت هناك نقطتين وحدة زرقاء والاخرى خضراء فسوف يتم تقريب لون الزرق الى التركوازي. ويتم ذلك بحساب المتوسط لكل 9 نقاط في الصورة .
Dim bmap As New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim red, green, blue As Integer Dim i, j As Integer With bmap For i = 1 To .Height - 2 For j = 1 To .Width - 2 red = CInt((CInt(.GetPixel(j - 1, i - 1).R) + _ CInt(.GetPixel(j - 1, i).R) + _ CInt(.GetPixel(j - 1, i + 1).R) + _ CInt(.GetPixel(j, i - 1).R) + _ CInt(.GetPixel(j, i).R) + _ CInt(.GetPixel(j, i + 1).R) + _ CInt(.GetPixel(j + 1, i - 1).R) + _ CInt(.GetPixel(j + 1, i).R) + _ CInt(.GetPixel(j + 1, i + 1).R)) / 9) green = CInt((CInt(.GetPixel(j - 1, i - 1).G) + _ CInt(.GetPixel(j - 1, i).G) + _ CInt(.GetPixel(j - 1, i + 1).G) + _ CInt(.GetPixel(j, i - 1).G) + _ CInt(.GetPixel(j, i).G) + _ CInt(.GetPixel(j, i + 1).G) + _ CInt(.GetPixel(j + 1, i - 1).G) + _ CInt(.GetPixel(j + 1, i).G) + _ CInt(.GetPixel(j + 1, i + 1).G)) / 9) blue = CInt((CInt(.GetPixel(j - 1, i - 1).B) + _ CInt(.GetPixel(j - 1, i).B) + _ CInt(.GetPixel(j - 1, i + 1).B) + _ CInt(.GetPixel(j, i - 1).B) + _ CInt(.GetPixel(j, i).B) + _ CInt(.GetPixel(j, i + 1).B) + _ CInt(.GetPixel(j + 1, i - 1).B) + _ CInt(.GetPixel(j + 1, i).B) + _ CInt(.GetPixel(j + 1, i + 1).B)) / 9) bmap.SetPixel(j, i, Color.FromArgb(red, green, blue)) Next PictureBox1.Refresh() ' Me.Text = Int(100 * i / (PictureBox1.Image.Height - 2)).ToString & "%" Next End With PictureBox1.Refresh() Me.Text = "Done smoothing image" End Sub
(اتبع نفس الخطوات السابقة في عكس الوان الصورة )
كما تلاحظ فان الكود متطابق في بدايته مع كود عكس الوان الصورة .
واحب ان اوضح نقطة وهي -2 الموجودة في التكرار و فائدتها هي استبعاد اطراف الصورة من العملية .
المتغير red : قمنا بجمع قيم الالوان لكل 9 نقاط متجاورة ذات اللون الاحمر ومن ثم قسمتها على 9 لحساب المتوسط .
و كذلك المتغير blue و المتغير green .
و لو جربت ان تحذف عملية المتغير green و المتغير red فان الصورة ستصبح زرقاء تماما .
يا جماعة وين التعليقات . هل الامر صعب ؟ ام ماذا ؟
بصراحة شي فوق الرائع من زمان مستني موضوع التعامل مع ملفات الصور
ياريت تستفيض فية أخ عبد الحمن
مشكور على الجهد المبذول ووفقك الله
تحديد الصور Sharpening
من المعروف ان تحديد الصورة هو عكس تمليسها . و لتحديد صورة يجب ان نجد خزارزمية معينة تبين او تزيد الفرق بين النقاط المختلفة اصلا .
لانه من غير الممكن ان نحدد صورة زرقاء تماما و ليس بها نقاط مختلفة .
لذلك السؤال هو ما هي الخوارزمية التي تزيد الفرق بين النقاط المتجاورة المختلفة اصلا (ذات اللون المختلف) و لا تؤثر على النقاط المتجاورة المتطابقة (ذات اللون الواحد) ؟؟
الجواب هو ان تضيف الفرق بين النقطة الاصلية و النقطة المجاورة الى النقطة الاصلية . و بالتالي اذا كانت النقطتان المتجاورتان ذات لون واحد فان الفرق سيساوي صفر و بالتالي لن تؤثر عليها , وانما التاثير (زيادة الفرق) سيكون على النقاط التي سيكون بين قيمها فرق . و اليك الكود الذي سيوضح العملية :
Dim bmap = New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim red, green, blue As Integer Dim i, j As Integer With bmap For i = 1 To .Height - 2 For j = 1 To .Width - 2 red = CInt(.GetPixel(j, i).R) + _ 0.5 * CInt((.GetPixel(j, i).R) - CInt(.GetPixel(j - 1, i - 1).R)) If red < 0 Then red = red * -1 green = CInt(.GetPixel(j, i).G) + _ 0.5 * CInt((.GetPixel(j, i).G) - CInt(.GetPixel(j - 1, i - 1).G)) If green < 0 Then green = green * -1 blue = CInt(.GetPixel(j, i).B) + _ 0.5 * CInt((.GetPixel(j, i).B - CInt(.GetPixel(j - 1, i - 1).B))) If blue < 0 Then blue = blue * -1 red = Math.Min(red, 255) green = Math.Min(green, 255) blue = Math.Min(blue, 255) bmap.SetPixel(j, i, Color.FromArgb(red, green, blue)) Next PictureBox1.Refresh() Next End With PictureBox1.Refresh() Me.Text = "Done sharpening image"
دعنا ناخذ المتغير red مثلا : j , i هي النقطة الاصلية , اضفنا اليها الفرق بينها و بين النقطة المجاورة . اما عن الضرب في 0.5 فهو لتقليل حجم التفصيل او الفرق الحاصل . (يمكنك القسمة على 2 بدلا من الضرب في 0.5 ) .
و بعد حساب red يجب التاكد من ان قيمتها موجبة . فاذا كانت سالبة فاننا نضربها ب -1 لتصبح موجبة, لان قيم الالوان بين 0 و 255 . و للتاكد من ان قيمة red اقل او تساوي 255 فاننا نستخدم هذا الكود :
red = Math.Min(red, 255)
الدالة Min تعيد القيمة الاصغر بين قيمتين محددتين , فاذا كانت red اكبر من 255 فان red ستصبح 255 حسب الدالة Min .
و هكذا المتغيرين green و blue .
و لكن لو جربت العملية فستلاحظ ان التنفيذ بطيء للغاية . و لستريعه قليلا فاننا نستخدم صورة مؤقتة في الذاكرة . و اليك الكود:
Dim bmap = New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim red, green, blue As Integer Dim tempbmp As New Bitmap(PictureBox1.Image) Dim i, j As Integer With tempbmp For i = 1 To .Height - 2 For j = 1 To .Width - 2 red = CInt(.GetPixel(j, i).R) + _ 0.5 * CInt((.GetPixel(j, i).R) - CInt(bmap.GetPixel(j - 1, i - 1).R)) If red < 0 Then red = red * -1 green = CInt(.GetPixel(j, i).G) + _ 0.5 * CInt((.GetPixel(j, i).G) - CInt(bmap.GetPixel(j - 1, i - 1).G)) If green < 0 Then green = green * -1 blue = CInt(.GetPixel(j, i).B) + _ 0.5 * CInt((.GetPixel(j, i).B - CInt(bmap.GetPixel(j - 1, i - 1).B))) If blue < 0 Then blue = blue * -1 red = Math.Min(red, 255) green = Math.Min(green, 255) blue = Math.Min(blue, 255) bmap.SetPixel(j, i, Color.FromArgb(red, green, blue)) Next PictureBox1.Refresh() Next End With PictureBox1.Refresh() Me.Text = "Done sharpening image"
و مع ذلك فان الاداء غير مرضي لان العملية بطيئة جدا مقارنة مع برامج الرسم زي الفوتو شوب . و هذا يدل على ان هناك خوارزميات اخرى للتعامل مع مثل هذا النوع من معالجة الصور .
ارجو ان تكون قد استمتعت مع الدرس . و بصراحة هذي افكار تطور قدراتك البرمجية لذلك ارى انه يجب ان نخوض اكثر في الخوارزميات و الافكار و الحيل البرمجية .
ارجو منكم الدعاء و شكرا :)
بصراحة يوم عن يوم بزيد أعجابي في هذة اللغة والفضل يعود للك أخ عبد الرحمن وفقك الله وجعلة هذة الدروس في ميزان حسناتك
اشكرك اخ jarour على هذا الاطراء :)
ولكن هل من احد يعرف طريقة لتسريع عملية تحديد الصور ؟
أخي عليك بتوابع Api
فهي تسرع الموضوع كثيرا
عندي كود بأستخدام Api بس على Vb6
مابعرف إذا بيفيدك
انسى vb6 .
و ساحاول استخدام دوال ال API .
وبصراحة وضع الاخوة ما يحمس لانه ما في الا الاخ JAROUR اللي شغال معي .
فما رايكم ؟
لتسريع عمليات معالجة الصور السابقة قم بتغير الكود من
Dim bmap = New Bitmap(PictureBox1.Image)
الى
Dim bmap As New Bitmap(PictureBox1.Image)
(فكرة الاخ ابو عابد)
زخرفة الصور Embossing
اعتقد ان الجميع يعرف الفلتر المسمى Emboss و الموجود في برامج تحرير الصور المشهورة مثل الفوتوشوب . يقوم هذا الفلتر بابراز براويز او حواف الكائنات الموجودة في الصورة .
يمكننا عمل ذلك بالقيام باخذ الفارق بين كل نقطتين متجاورتين . ولكن غالبا يكون هذا الفارق ضئيل و بالتالي ستظهر الصورة غامقة و لذلك يجب عليك اضافة رقم الى هذا الفارق (مثلا 100 او 128 او 150 ) لزيادة اضاءة الصورة .
new_value = difference + 128
و اليك الكود الخاص بهذه العملية :
Dim bmap As New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim i, j As Integer Dim red, green, blue As Integer With bmap For i = 0 To .Height - 2 For j = 0 To .Width - 2 Dim pixel1, pixel2 As System.Drawing.Color pixel1 = .GetPixel(j, i) pixel2 = .GetPixel(j + 1, i + 1) red = Math.Min(Math.Abs(CInt(pixel1.R) - CInt(pixel2.R)) + 128, 255) green = Math.Min(Math.Abs(CInt(pixel1.G) - CInt(pixel2.G)) + 128, 255) blue = Math.Min(Math.Abs(CInt(pixel1.B) - CInt(pixel2.B)) + 128, 255) bmap.SetPixel(j, i, Color.FromArgb(red, green, blue)) Next PictureBox1.Refresh() Next End With PictureBox1.Refresh() Me.Text = "Done embossing image"
كم تلاحظ فان المتغيرين Pixel1 , Pixel2 هما عبارة عن نقطتين متجاورتين في الصورة .
لنأخذ اللون الاخضر مثلا :
green = Math.Min(Math.Abs(CInt(pixel1.G) - CInt(pixel2.G)) + 128, 255)
* الدالة Min تعيد القيمة الاصغر بين قيمتين . وهي بالتالي تضمن بان القيمة لن تتجاوز ال 255 .
* الدالة Abs تعيد القيمة المطلقة للقيمة . فاذا كانت القيمة سالبة فان الدالة تحولها الى قيمة موجبة . وهي بالتالي تضمن بان القيمة لن تكون سالبة .
مشكور أخي عبد على هذا الأطراء
بدك تطول بالك الموضوع لسة جديد وبيلاقي أقبال إن شاء الله
;) حقيقتاً بعد قرءاة مشاركات المبدع عبدالرحمن .. أصبح لي حماساً خاصاً في تعلم VB.NET
(clock) أتمنى منك عدم ترك هذا العلم لغير النشر والتعليم لأمثالي كل جديد ..
ولي طلب منك : كيفية البدء في برنامج يعمل تحت نظام الويندوز .. حيث أنني بدأت تعلم Console فقط وهنا وقفت !!
أو شرح الدالات والأوامر التي تبدأ بها لعمل برنامج في الويندوز .
ملاحظة : قمت بتجميع كل ما تكتبه في هذا المنتدى في ملف خاص عندي خوفاً من مسحه أو حذفه مع الأيام من المنتدى لأسباب فنية أو خلافه ..
ghazi1970@yahoo.com
دع الأيام تفعل ما تشاء .. وطب نفساً إذا حكم القضاء
مشكوووور أخ عبدالرحمن :)
اقتباسبدك تطول بالك الموضوع لسة جديد وبيلاقي أقبال إن شاء الله
انا معاك و قربيا ان شاء الله
:)
أخي عبد الرحمن
ذكرت في مرة سابقة كيف تتم عملية تحيل الملفات للIIS وقد جربتها ولم تعمل بالطريقة المطلوبة فهل يمكنك مساعدتي
وجزاك الله كل خير
اخ masaaq : اشكرك على التشجيع .
اخ ghazi :اتمنى لك التوفيق . و بالنسبة لجعل برنامجك يشتغل مع بدء الويندوز فقم ببساطة بنسخ برنامج (برمجيا طبعا) الى هذا المسار في جهازك Start MenuProgramsStartup . و يمكنك عمل ذلك باستخدام الريجستري و لكنها حتما ستكون اعقد من ذلك .
اخ sharp7 : انا معكم ايضا , و لكني عندما اكتب عدة دروس ورا بعض و لا اجد تفاعل من الاعضاء فان شيئا من الاحباط يصيبني . و لكن احتسب الاجر عند الله عز و جل .
اخ بيلسان : بصراحة لم افهم سؤالك جيدا .
و اعتذر على التاخير الذي حصل و ذلك بسبب عطل في Visual Studio .NET عندي .
تغبيش الصور Diffusing
بصراحة لم اجد معنى مناسب لكلمة Diffuse . و لكن ستعرف معناها جيدا اذا طبقت الكود . كود تغبيش الصورة يعتمد على جعل الصورة نقاط عشوائية . هذه النقاط العشوائية نقوم بانشائها باستخدام الدالة rnd . و اليك الكود الذي سيبين لك العملية :
Dim bmap = New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim tempbmp As New Bitmap(PictureBox1.Image) Dim i As Integer, j As Integer Dim DX As Integer Dim DY As Integer Dim red As Integer, green As Integer, blue As Integer With tempbmp For i = 3 To .Height - 3 For j = 3 To .Width - 3 DX = Rnd() * 4 - 2 DY = Rnd() * 4 - 2 red = .GetPixel(j + DX, i + DY).R green = .GetPixel(j + DX, i + DY).G blue = .GetPixel(j + DX, i + DY).B bmap.SetPixel(j, i, Color.FromArgb(red, green, blue)) Next PictureBox1.Refresh() Next End With PictureBox1.Refresh() Me.Text = "Done diffusing image" End Sub
لاحظ اننا اسندنا القيمة Rnd() * 4 - 2 للمتغيرين DX , DY . استخدمت -2 لكي اتحاشى حواف الصورة , والا فان خطأ ما سيحدث .
لاحظ ايضا انه كلما زدنا قيمة الرقم العشوائي (4 , 5 , 6 ) فان العملية ستزيد تركيزا . جربها بنفسك .
و احب ان اوضح انه بدون انشاء متغير tempbmp فان العملية ستكون بطيئة جدا و غير مرتبة لان العملية ستؤثر على الصورة نفسها في كل امر و عملية حسابية في حلقة التكرار . و لكن بالمتغير tempbmp فاننا نقوم بالحسابات في الخلفية Background واما التطبيق بالدالة SetPixel فيكون على الصورة نفسها وذلك بالمتغير bmap و بالتالي تكون العملية اسرع و اجمل .
الأخ عبدالرحمن
بارك الله فيك و يعطيك العافيه على هذا الجهد الرائع.
(yess)
أتمنى أن تغطي موضوع الاتصالات بين الاجهزة عن الشبكة المحلية أو عن طريق الاتصال عبر خط الهاتف. أو أن تدلني على مصدر ما يفيدني بهذا الموضوع.
و لكم مني جزيل الشكر.
أخ جمال : إن شاء الله راح نغطي موضوع الشبكات و الاتصالات و المودم و غيرها من الامور المتعلقة بهذا الامر .
الاضاءة في الصور Brightness
هل تساءلت يوما عن كيفية تكثيف و تقليل درجة الاضاءة في الصور ؟
الفكرة بسيطة جدا لان فجوال بيسك .نت يدعم خاصية اسمها الفا alpha يمكنك من خلالها تغيير درجة شفافية الصورة . اظن ان الفكرة قد وضحت و اليك الكود الذي يقوم بتقليل درجة الاضاءة في صورة :
PictureBox1.BackColor = Color.Black Dim bmap = New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim tempbmp As New Bitmap(PictureBox1.Image) Dim red, green, blue As Integer Dim i, j As Integer With tempbmp For i = 1 To .Height - 2 For j = 1 To .Width - 2 red = CInt(.GetPixel(j, i).R) green = CInt(.GetPixel(j, i).G) blue = CInt(.GetPixel(j, i).B) bmap.SetPixel(j, i, Color.FromArgb(200, red, green, blue)) Next PictureBox1.Refresh() Next End With PictureBox1.Refresh()
كما تلاحظ فاننا في بداية الكود قمنا بتغيير لون الخلفية لاداة مربع الصورة الى الاسود ثم قمنا بتغيير قيمة الفا للصورة تساوي 200 . و قيمتها بين 0 و 255 .
255 : غير شفافة .
0 : شفافة تماما .
و الخاصية الفا هي اول تابع في الدالة SetPixel .
و اذا اردت ان تجعل الصورة اكثر اضاءة فاجعل الخلفية بيضاء white .
الالوان في الصور
اذا اردت ان تجعل صورتك زرقاء مثلا فاجعل قيمة اللون الاحمر و الاخضر تساوي صفر
Dim bmap = New Bitmap(PictureBox1.Image) PictureBox1.Image = bmap Dim tempbmp As New Bitmap(PictureBox1.Image) Dim red, green, blue As Integer Dim i, j As Integer With tempbmp For i = 1 To .Height - 2 For j = 1 To .Width - 2 red = CInt(.GetPixel(j, i).R) green = CInt(.GetPixel(j, i).G) blue = CInt(.GetPixel(j, i).B) bmap.SetPixel(j, i, Color.FromArgb(0, 0, blue)) Next PictureBox1.Refresh() Next End With PictureBox1.Refresh()
و اذا اردت مثلا ان تحذف اللون الاخضر في صورتك فاجعل قيمة اللون الاخضر تساوي صفر .
و اظن ان هذه العملية موجودة في فوتو شوب و تسمى ب Channels .
و كما تلاحظون فاننا قد عملنا كثير من العمليات الموجودة في الفوتو شوب و يبقى علينا الكثير ايضا . و لكني انتظر الافكار . فاتمنى ان نتعاون جميعا و نقوم بصنع برنامج يقوم بمثل هذه العمليات الرائعة فعلا و المثيرة للاهتمام .
والله يا أخي من زمان ماشفت مثل هذا الشي إن شاء الله في القريب رح أنزل مشاركات عن إستحدام توابع API في VB NET والمكافئات لها في البرمجة بعد أذنك طبعا أخ عبد الرحمن
هذا الموضوع مغلق.
المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية
جارٍ التحقق من المتواجدين…