المحتويــات
- المقدمة
- معالجة الصورة باستخدام مكتبة المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )في برمجة البايثون
- قراءة الصور وعرضها على الشاشة
- الحصول على خصائص الصورة عدد بكسلاتها وأبعادها
- قنوات ألوان الصورة
- التحويل إلى التنسيق الرماديّ
- تغيير حجم الصورة
- حفظ الصورة
- اقتصاص الصورة
- الحصول على الهيستوغرام من الصورة:
- إجراء دوران للصورة
- الرّسم على الصورة
- كشف الحوافّ في الصورة
- العتبة
- التآكل والتوسع
- الخاتمة
- المراجع
المقدّمة
إن كنت مهتماً بالتعرّف على الوجوه ضمن صورة أو فيديو ما، أو كنت ممن يهتمّ بتقنيات التعلم العميق في تصنيف الصور، أو ممن لديه مشروع على راسبيري باي ( Raspberry Pi ) وتودّ إضافة التعرّف على الصور إلى مشروعك فأنت تحتاج إلى المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv ).
يُقال إنّ الرؤية الحاسوبيّة هي من أكثر التطبيقات المثيرة للاهتمام في مجال التعلم الآليّ، كما يوحي اسمها إلى إمكانيّة الحاسب من اكتشاف وتحديد وتمييز الكائنات والأنماط في المحيط ثلاثيّ الأبعاد.
إنّ معالجة الصورة أحد أفرع علوم الحاسوب، وهي طريقة لإجراء بعض العمليّات على صورة من أجل الحصول على نموذج محسن لهذه الصورة، أو استخراج بعض المعلومات المفيدة منها. غالبًا البيانات التي نجمعها تكون بيانات أوليّة أي أنها غير مناسبة للاستخدام المباشر في التطبيقات، لذلك نحتاج إلى تحليل أو إجراء المعالجة المسبقة لها ومن ثمّ استخدامها.
على سبيل المثال: تريد بناء مجموعة بيانات تستخدمها في نموذج يصنف الصور، فيما إذا كانت تحتوي على منزل أو لا بالاعتماد على صورة كدخل لهذا البرنامج، الخطوة الأولى ستكون جمع المئات من صور المنازل، لكن المشكلة تكمن في أنّ هذه الصور لن تكون بنفس الأبعاد مثلًا لذلك سنحتاج إلى تغيير أبعادها، أي معالجتها مسبقًا قبل تقديمها إلى النموذج.
ما سبق هو واحد من العديد من الأسباب التي تجعل من معالجة الصورة أمرًا مهمًّا لأيّ تطبيق يعتمد على الرؤية الحاسوبيّة Computer Vision .
سيساعدك هذا المقال في اكتساب المعرفة فيما يتعلق بتقنيات الرؤية الحاسوبيّة التي تستخدم برمجة بايثون Python، سأشرح هنا كيفيّة تنفيذ توابع الرؤية الحاسوبيّة وتنفيذها في جوانب مختلفة، وتجربة بعض الأمثلة البارزة، ثمّ إظهار نتيجة الخرج مع الرّسوم التوضيحيّة. أخيرًا، سنتناول أيضًا معالجة الصور الأساسيّة وتنفيذ توصيف محدّد لتوابع الرؤية الحاسوبيّة.
ستقدّم لك هذه المقالة المزيد من ميزات مكتبة المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )فلنبدأ في تعلم أساسيّات المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )في معالجة الصور.
معالجة الصورة باستخدام مكتبة المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )في برمجة البايثون :
إنّ مكتبة المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )مفتوحة المصدر من تطوير شركة انتل (Intel) مبنيّة على لغة البرمجة c++، تُعتبر الأكثر استخدامًا في معالجة الصورة والرؤية الحاسوبيّة، غنيّة بالطرق والتوابع التي تسهل عمليّات التعامل مع الصور و معالجتها، حيث يمكننا قراءة الصور و إجراء العديد من العمليّات عليها كتحويل الصور الملوّنة RGB إلى صور رماديّة grayscale ، واقتصاص الصورcropped، وتغيير أبعاد الصورresizing، وتحليل الصور كالحصول على الهيستوغرام والكثير من العمليّات الأخرى، سوف نستعرض بعضها في هذا المقال.
قراءة الصور وعرضها على الشاشة
نريد الآن قراءة صورة، يتمّ ذلك باستخدام التابع ()imread الذي يأخذ مسار الصورة مع اسمها كوسيط، ومن ثمّ عرضها على الشاشة باستخدام التابع ()imshow الذي يأخذ الصورة المقروءة كوسيط له فيكون الكود البرمجيّ :
الشكل-1 الصورة المطلوب قراءتها
ملاحظة:
يمكنك استبدال C:/Users/Shivek/Pictures/image1 بموقع الصورة المخزّنة في جهازك الخاص.
يقوم الكود أعلاه بتحميل الصورة المطلوبة بنجاح في ذاكرة نظامنا وبتنسيق ألوان رمادي GRAYSCALE.
import cv2
# load it in GRAYSCALE color mode...
image = cv2.imread("""C:/Users/Shivek/Pictures/image1.jpg""", 0)
cv2.imshow('Analytics Vidhya Computer Vision- Nature.png Gray', image)
cv2.waitKey()
cv2.destroyAllWindows()
الحصول على خصائص الصورة، عدد بكسلاتها وأبعادها
سيتمّ استخدام الطريقتين size ، shape . بدايةً سنشرح بعض المفاهيم الأساسيّة المتعلقة بالصور.
ما هو البكسل؟
تتكوّن جميع الصور من البكسلات، والتي تعد اللبنات الأساسيّة للصور. مثلًا صورة بحجم 640 × 480 بها 640 عمودًا (العرض) و 480 صفًا (الإرتفاع)، أي هناك 640 * 480 = 307200 بكسل في الصورة بهذه الأبعاد.
كلّ بكسل في صورة ذات تدرّج رماديّ له قيمة تمثل قيمة سوية لونيّة رماديّة. في المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )، هناك 256 قيمة سوية لونيّة رماديّة من 0 إلى 255.
تحتوي البكسلات الموجودة في الصورة الملوّنة على معلومات إضافيّة، وهناك العديد من مساحات الألوان مثل (RGB,HVS,..) من أجل التبسيط دعنا نأخذ في الاعتبار مساحة ألوان RGB فقط.
تعرض المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )الصور بتنسيق BGR (أحمر، أخضر، أزرق) أي كلّ بكسل له قيمة من أجل كلّ من (B,G,R).
دعنا نلقي نظرة على صورتنا من خلال عرض الخصائص عبر الطريقة shape
print(image.shape)
الخرج سيكون على النحو التالي:
(456,768)
أما عند استخدام الطريقة size
print(image.size)
الخرج سيكون على النحو التالي:
350208
لاحظ أنّ الطريقة shape تُرجع إلينا قيمتين على شكل مجموعة، تمثل هاتان القيمتان الارتفاع (المحور y) والعرض (المحور X) للصورة على التوالي.
print("The Image Height Is: %d Pixels"%(image.shape[0]))
print("The Image Width Is: %d Pixels"%(image.shape[1]))
خرج الكود السابق سيكون على النحو التالي:
The Image Height Is: 456 Pixels
The Image Width Is: 768 Pixels
هناك بعض الوضعيّات للطريقة Shape تُرجع مجموعة من 3 قيم صحيحة، وهي الارتفاع والعرض وعدد قنوات الألوان.
تؤثر قنوات الألوان على نطاقات الألوان (أي أنواع / ظلال الألوان | الأحمر والأزرق والورديّ وما إلى ذلك) لوحدات البكسل. بأخذ مثالنا، لدينا صورة GRAYSCALE حيث تحتوي صورة على قناة ألوان واحدة فقط، لأنّ كلّ عنصر في مصفوفة البكسل يحتوي على قيمة واحدة فقط تتراوح من 0 إلى 255.
قنوات ألوان الصورة
على سبيل المثال، ولأغراض التجربة، دعنا نعيد قراءة صورتنا الطبيعيّة، ونعرض خصائص الـ Shape ومع ذلك، في هذه الحالة بالذات، نقوم بتحميل الصورة بتنسيق الألوان القياسيّ.
import cv2
# re-load it in color mode...
image = cv2.imread("C:/Users/Shivek/Pictures/cd0c13629f217c1ab72c61d0664b3f99.jpg", cv2.IMREAD_COLOR)
cv2.imshow('Analytics Vidhya Computer Vision- Nature.png Color', image)
cv2.waitKey()
cv2.destroyAllWindows()
ستظهر الصورة الملوّنة على النحو التالي:
الشكل-3 خرج الكود السابق
صورتنا الملوّنة كما تمّ تنزيلها أي لم يتمّ التلاعب بها بأيّ شكل من الأشكال. الآن دعونا ننتقل إلى استخدام طريقة Shape على هذه الصورة.
print(image.shape)
print("Image Height: %d Pixels"%(image.shape[0]))
print("Image Width: %d Pixels"%(image.shape[1]))
print("Number Of Color Channels: %d "%(image.shape[2]))
سيظهر خرج الكود أعلاه على النحو التالي:
(456,768,3)
The Image Height Is: 456 Pixels
The Image Width Is: 456 Pixels
Number of Color Channels: 3
لاحظ وجود رقم ثالث في المجموعة، وهو عدد قنوات الألوان الموجودة في الصورة. قناة اللون المعينة الموجودة في هذه الصورة هي BGR Color Channel إنه BGR وليس RGB بشكل افتراضيّ، تمّ إنشاء المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )لاستخدام BGR Color Channel.
نظرًا لأنّ الصورة باللون القياسيّ، فبالنظر إلى الصورة يمكن للمرء أن يرى عدّة تدرّجات لونية. هذا بسبب وجود ثلاث قنوات لونيّة، حيث كلّ عنصر من عناصر مصفوفة البكسل، له ثلاث قيم تتراوح من 0 إلى 255 وتمثل كلّ قيمة شدة ) BGRأزرق ، أخضر ، أحمر) عند هذا البكسل وبالتالي السماح بمزج الألوان.
التحويل إلى التنسيق الرماديّ
نستخدم التابع cvtColor ونمرّر له وسيطين الأوّل هو الصورة المراد تحويلها و الثاني cv.COLOR_BGR2GRAY الذي يعبر عن نمط التحويل من الصورة الملوّنة إلى اللون الرماديّ ويكون الكود البرمجيّ :
import cv2
# load the image in color mode...
image = cv2.imread("C:/Users/Shivek/Pictures/cd0c13629f217c1ab72c61d0664b3f99.jpg", cv2.IMREAD_COLOR)
grayImg=cv2.cvtcolor(image,COLOR_BGR2GRAY)
cv2.imshow(grayImg)
cv2.waitKey(0)
بعد تنفيذ الكود السابق نحصل على النتيجة التالية:
الشكل-4 الصور قبل إجراء التحويل وبعده
بالعودة إلى صورة التدرج الرمادي GRAYSCALE الخاصة بنا، سنحاول الآن تغيير حجم الصورة لجعلها بأبعاد أصغر . وبالتالي نحتاج لتغيير أبعاد الصورة إلى استخدام طريقة resize التي تقدّمها المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv ).
import cv2
# load the image in a GRAYSCALE format
image = cv2.imread("C:/Users/Shivek/Pictures/cd0c13629f217c1ab72c61d0664b3f99.jpg", cv2.IMREAD_GRAYSCALE)
cv2.imshow('Analytics Vidhya Computer Vision- Nature Standard Image', image)
cv2.waitKey()
cv2.destroyAllWindows()
# resize the image to be pixel dimensions 350 by 350
resized_image = cv2.resize(image, dsize=(350, 350))
cv2.imshow('Analytics Vidhya Computer Vision- Nature Resized (350, 350)', resized_image)
cv2.waitKey()
cv2.destroyAllWindows()
سيتمّ شرح الكتلة الثانية من الكود:
resized_image = cv2.resize(src=image, dsize=(350, 350))
نحن نستخدم طريقة resize لتغيير حجم الصورة، وهذا قد يعني إما زيادة الحجم أو تصغيره، اخترنا تصغير حجم الصورة في مثالنا هذا. تأخذ هذه الطريقة بارامتريين أساسيين:
البارامتر الأوّل: تحديد الصورة التي سيتمّ تغيير حجمها.
1……src = The Source Image (Image to be resized)
البارامتر الثاني: تحديد الأبعاد الجديدة (الطول /العرض) المطلوبة للصورة الجديدة الناتجة، وفي مثالنا كان كلاهما بقيمة 350.
2….. dsize = The Desired Size.
cv2.imshow('Analytics Vidhya Computer Vision- Nature Resized (350, 350)', resized_image)
cv2.waitKey()
cv2.destroyAllWindows()
إنّ ما تفعله هذه الأسطر الثلاثة من الكود أعلاه هي عرض النافذة، وانتظار فترة زمنيّة غير محدّدة، وإنهاء جميع النوافذ بناءً على أمر المستخدم.
ستكون المهمة الأخيرة بالنسبة لنا هي التحقق من أنّ حجم الصورة قد تمّ تصغيره.
سيظهر الخرج على النحو التالي:
الشكل -5 نتيجة تطبيق () resize
حفظ الصورة
نريد الآن قراءة صورة وحفظها باسم جديد في مسار آخر على الحاسوب باستخدام التابع()imwrite، نمرّر له وسيطين، الأوّل المسار الذي أريد الحفظ فيه واسم الصورة عن طريق الدّمج بينهم باستخدام ()path.join من مكتبة النظام os المضمنة في بايثون، والثاني هو الصورة المقروءة .
يكون الكود البرمجيّ لتحقيق ذلك:
import cv2
import os
# load the image in a GRAYSCALE format
image = cv2.imread("C:/Users/Shivek/Pictures/cd0c13629f217c1ab72c61d0664b3f99.jpg", cv2.IMREAD_GRAYSCALE)
path= 'c\\User\\Windows.10\\Desktop'
cv2.imwrite (os.path.join(path,"newImg.png"),image)
cv2.waitKey(0)
وبالنظر إلى سطح المكتب يمكننا التأكد من أنه تمّ إنشاء صورة تحمل الاسم newImg.png .
اقتصاص الصور
نريد اقتصاص جزء من الصورة والمحافظة عليه، نقوم بقراءة صورة والحصول على عرضها وارتفاعها ومن ثمّ تحديد سطر بداية الاقتصاص وسطر النهاية وعمود البداية وعمود النهاية، يُحدد مجال الاقتصاص بالقيم السابقة كي نحصل على الجزء الذي نريده من الصورة، ويكون البرنامج كالآتي:
import cv2
# load the image in color mode...
image =cv2.imread("C:/Users/Shivek/Pictures/flower.jpg",cv2.IMREAD_COLOR)
height,width=image.shape[0:2]
startRow = int(height*.15)
endRow = int(height*.85)
startCol = int(width*.15)
endCol = int(width *.85)
croppedImage = image [startRow : endRow , startCol : endCol]
cv2.imshow (croppedImage)
cv2.waitKey(0)
وتكون نتيجة تنفيذ المقطع البرمجيّ السابق:
الشكل-6 الصور قبل وبعد تطبيق الاقتصاص
الحصول على الهيستوغرام من الصورة
يعتبر الهيستوغرام بمثابة مخطط أو رسم بيانيّ ثنائي البعد يصف كثافة أو تكرار قيم السويات اللونية الموجودة في الصورة، باستخدام التابع ()calcHist
الشكل العام لهذا التابع:
calcHist([image],channel ,mask ,[histSize],[color range])
نمرّر له الصورة والقناة اللونيّة، في مثالنا نمرّر القيمة 0 التي تشير إلى أنّ الصورة رماديّة، والـ mask نعطيه القيمة None للحصول على الهيستوغرام للصورة كاملةً، ومن ثمّ حجم الهيستوغرام 256، و أخيرًا مجال القيم اللونيّة من 0 حتى 255 والذي يعبر عن القيم التي تأخذها الألوان، نقوم برسم الهيستوغرام المحسوب باستخدام التابع plot() من مكتبةُ الرَّسمِ الرِّياضيِّ في بايثون (ماتبلوت) matplotlib فيكون الكود البرمجيّ :
import cv2
from matplotlib import pyplot as plt
grayImg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
hist = cv2.calcHist([grayImg],[0],None,[256],[0,256])
plt.plot(hist)
plt.show()
cv2.waitKey(0)
وتكون نتيجة تنفيذ المقطع السابق:
إجراء دوران للصورة
يتطلب تدوير صورة حول النقطة المركزيّة أن نحسب أوّلاً إحداثيّات المركز (x,y) للصورة.
ملاحظة // تعني من أجل قيم رياضيّة صحيحة.
من ثمّ تُحسب مصفوفة الدّوران M من خلال التابع getrotationMatrix2d، حيث -45 تعني أننا سندير الصورة 45 درجة في اتجاه عقارب الساعة.
ومن ثمّ تطبيق مصفوفة الدّوران على الصورة من خلال التابع warpAffine. الشكل أدناه يعرض نتيجة التدوير.
mport cv2
image =cv2.imread("C:/Users/Shivek/Pictures/doctors.jpg",cv2.IMREAD_COLOR)
h,w =image.shape[0:2]
center = (w//2 , h//2)
M=cv2.getrotationMatrix2d(center,-45,1.0)
Rotated=cv2.warpAffine(image,M,(w,h))
Cv2.imshow("(OpenCv )Rotation", Rotated)
Cv2.waitkey(0)
الرسم على الصورة
في هذه الفقرة، سنقوم برسم مستطيل ودائرة وخطٍّ على صورة الدّخل، وسنقوم أيضًا بادراج النص على الصورة أيضًا. قبل أن ننتقل إلى الرّسم على صورة باستخدام المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ OpenCV، لاحظ أنّ في بداية كلّ مقطع من البرنامج نقوم بعمل نسخة من الصورة الأصليّة لتخزين النسخة كخرج، ثمّ ننتقل بعد ذلك إلى الرّسم على الصورة التي تسمى الخرج في المكان حتى لا نتلف صورتنا الأصليّة.
لنرسم مستطيلاً حول وجه إيان مالكولم:
import cv2
image =cv2.imread("C:/Users/Shivek/Pictures/doctors.jpg",cv2.IMREAD_COLOR)
# draw a 2px thick red rectangle surrounding the face
Output = image.copy ()
cv2.rectangle(output, (320, 60), (420, 160), (0, 0, 255), 2)
cv2.imshow (output)
Cv2.waitkey(0)
سنوضح بارامترات التابع cv2.rectangle:
البارامتر الأوّل يمثل الصورة المطلوب الرّسم عليها
البارامتر الثاني يمثل إحداثيّات بكسل البداية الخاصة بنا وهي أعلى اليسار، في مثالنا إحداثيّات الأعلى اليسار هو (320، 60).
البارامتر الثالث إحداثيّات بكسل النهاية وهي أسفل اليمين، في مثالنا إحداثيّات السفليّ الأيمن هو (420، 160).
البارامتر الرّابع هو لون الرّسم ممثلةً بمجموعة اللون (B,G,R)، في مثالنا سيكون باللون الأحمر ممثلاً بهذه القيم (0, 0, 255).
البارامتر الخامس هو السماكة أي سمك خطّ الرّسم (القيمة السالبة ستشكل مستطيلاً مصمتاً)، في مثالنا الخط بسمك 2.
نظرًا لأننا نستخدم توابع المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )بدلًا من عمليّات مكتبةُ بايثون العدديَّةُ (NumPy)، يمكننا تزويد إحداثيّاتنا بترتيب (x، (y بدلًا من (y، (x نظرًا لأننا لا نتعامل مع NumPy أو نصل إليها مباشرةً حيث المكتبةُ المفتوحةُ للرُّؤيةِ الحاسُوبيَّةِ (OpenCv )ستتوّلى هذا الأمر، والشكل أدناه سيوضح النتيجة. عند رسم المستطيل حول الوجه لقد حددت مسبقًا الإحداثيات حول الوجه، ولكن يمكنك استخدام طريقة اكتشاف الوجه للعثور تلقائيًا على إحداثيات الوجه.
الشكل-9 رسم مربع أحمر باستخدام cv2.rectangle
لرسم دائرة زرقاء مصمتة أمام وجه الدّكتورة إيلي ساتلر:
import cv2
image =cv2.imread("C:/Users/Shivek/Pictures/doctors.jpg",cv2.IMREAD_COLOR)
# draw a blue 20px (filled in) circle on the image centered at
# x=300,y=150
Output = image.copy ()
cv2.circle(output, (300, 150), 20, (255, 0, 0), -1)
cv2.imshow (output)
Cv2.waitkey(0)
سنوضح بارامترات التابع cv2.circle:
البارامتر الأوّل يمثل الصورة المطلوب الرّسم عليها
البارامتر الثاني وهي إحداثيّات مركز الدّائرة، في مثالنا كانت (300، 150) والتي تقع أمام عينيّ الدّكتورة إيلي مباشرةً.
البارامتر الثالث وهي قيمة نصف قطر الدّائرة بالبكسل, في مثالنا 20 بكسل.
البارامتر الرّابع هو لون الرّسم ممثلة بمجموعة اللون (B,G,R)، في مثالنا سيكون باللون الأزرق ممثلًا بهذه القيم (255, 0, 0).
البارامتر الخامس هو السماكة، في مثالنا أعطينا الخط قيمة سالبة وبالتالي الشكل المرسوم مصمت، والشكل أدناه سيوضح النتيجة.
الشكل-10 رسم دائرة زرقاء باستخدام cv2.circle
لرسم خط أحمر، يمرّ هذا الخط برأس إيلي، وعينها، ويد إيان.
import cv2
image =cv2.imread("C:/Users/Shivek/Pictures/doctors.jpg",cv2.IMREAD_COLOR)
# draw a 5px thick red line from x=60,y=20 to x=400,y=200
Output = image.copy ()
cv2.line(output, (60, 20), (400, 200), (0, 0, 255), 5)
cv2.imshow (output)
Cv2.waitkey(0)
بملاحظة بارامترات cv2.line ومقارنتها بــ cv2.rectangle، ستلاحظ أنها متطابقة، تزويد بإحداثيّات نقطتين، لون، وسُمك خطّ الرسم، والشكل أدناه سيوضح النتيجة.
الشكل-11 رسم خط أحمر باستخدام cv2.line
ستجد في كثير من الأحيان أنك تريد إضافة نصّ على صورة لأغراض العرض، إذا كنت تعمل على التعرّف على الوجوه، فمن المحتمل أن ترغب في كتابة اسم الشخص فوق وجهه، أو إذا كنت تدرس في مجال الرؤية الحاسوبيّة، فيمكنك إنشاء مصنف صور أو كاشف كائن في هذه الحالات ستجد أنك تريد رسم نصّ يحتوي على اسم المصنف والاحتمال.
سنرى الآن كيف يعمل تابع putText في OpenCV:
import cv2
image =cv2.imread("C:/Users/Shivek/Pictures/doctors.jpg",cv2.IMREAD_COLOR)
# draw green text on the image
Output = image.copy ()
cv2.putText(output, " (OpenCv )+ Jurassic Park!!!", (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.imshow (output)
Cv2.waitkey(0)
تابع cv2.putText مسؤول عن رسم نصّ على صورة، سنوضح بارامترات هذا التابع:
البارامتر الأوّل يمثل الصورة المطلوب الرّسم عليها
البارامتر الثاني هو النص أي السلسلة النصيّة التي ترغب في كتابتها / رسمها على الصورة.
البارامتر الثالث هو إحداثيّات نقطة البداية للنص.
البارامتر الرّابع هو الخطّ غالبًا ما نستخدم cv2.FONT_HERSHEY_SIMPLEX فالخطوط المتاحة مدرجة بمثالنا.
البارامتر الخامس هو حجم الخط.
البارامتر السادس هو لون النص.
البارامتر السابع هو سماكة الخطّ بالبكسل.
إنّ الكود السابق سيرسم النص، (!!! OpenCv + Jurassic Park ) باللون الأخضر على الصورة كماهو موضح بالصورة أدناه.
الشكل-12 رسم نصّ باللون الأخضر على الصورة
كشف الحوافّ في الصورة
يعدّ اكتشاف الحوافّ مفيدًا في العثور على حدود الكائنات في الصورة، فهو فعال لأغراض التجزئة. باستخدام خوارزميّة Canny الشهيرة (التي طوّرها جون كاني John F. Canny في عام 1986)، يمكننا العثور على الحوافّ في الصورة.
import cv2
# applying edge detection we can find the outlines of objects in images
image =cv2.imread("C:/Users/Shivek/Pictures/shapes.jpg",cv2. IMREAD_GRAYSCALE)
edged = cv2.Canny(image, 30, 150)
cv2.imshow (edged)سنوضح
Cv2.waitkey(0)
الآن بارامترات التابع cv2.Canny والذي يأخذ أربع بارامترات:
البارامتر الأوّل يمثل الصورة المطلوب إيجاد كشف الحوافّ لها وتكون بتنسيق رماديّ.
البارامتر الثاني يمثل العتبة الدنيا في مثالنا قيمتها 30.
البارامتر الثالث يمثل العتبة العظمى في مثالنا قيمتها 150.
البارامتر الرّابع يمثل حجم Sobel kernel والذي يأخذ قيمة افتراضيّة 3 وهنا هذا البارامتر غير ظاهر في مثالنا.
ستُعيد القيم المختلفة للحدّ الأدنى والحدّ الأقصى خرائط حوافّ مختلفة.
الشكل-13 إجراء كشف الحوافّ للصورة
العتبـــة
تعدّ عتبة الصورة خطوة وسيطة مهمة في معالجة الصور، يمكن أن تساعدنا العتبة على إزالة المناطق الأفتح أو الأغمق من الصورة وخطوطها. أنا أشجعك بشدّة على تجربة العتبة، لقد ضبطت البرنامج التالي للعمل في مثالنا عن طريق التجربة والخطأ (بالإضافة إلى الخبرة):
import cv2
# applying edge detection we can find the outlines of objects in images
# threshold the image by setting all pixel values less than 225 to 255 (white; foreground) and all pixel values >= 225 to 255 (black; background), thereby segmenting the image
image =cv2.imread("C:/Users/Shivek/Pictures/shapes.jpg",cv2. IMREAD_GRAYSCALE)
thresh = cv2.threshold(image, 225, 255, cv2.THRESH_BINARY_INV)[1]
cv2.imshow (thresh)
Cv2.waitkey(0)
البرنامج الموضح أعلاه يعني انتزاع جميع وحدات البكسل في الصورة الرماديّة الأكبر من 225، وتعيينها على 0 (أسود) الذي يتوافق مع خلفيّة الصورة، وضبط قيم البكسل التي هي أقل من 225 إلى 255 (أبيض) الذي يتوافق مع الكائنات الظاهرة في الصورة.
الشكل-14 تطبيق العتبة على الصورة
لاحظ في الشكل رقم 15 أنّ الكائنات بيضاء والخلفيّة سوداء.
التآكل والتوسع
عادة ما تستخدم التآكل والتوسع لتقليل الضجيج في الصور الثنائيّة (أحد الآثار الجانبية للعتبة). لتقليل حجم الكائنات، يمكننا تآكل وحدات البكسل.
قمنا بنسخ الصورة الناتجة من المثال السابق (تطبيق العتبة ) وتسميتها mask، ثمّ استخدمنا cv2.erode، لتقليل أحجام الكنتور بـ 5 تكرارات وتكون النتيجة كما هي موضحة في الشكل أدناه.
الشكل-15 إجراء عملية التآكل
وبالمثال يمكننا إجراء عمليّة التوسعة، ما عليك سوى استخدام cv2.dilate:
import cv2
# we apply erosions to reduce the size of foreground objects
image =cv2.imread("C:/Users/Shivek/Pictures/shapes.jpg",cv2. IMREAD_GRAYSCALE)
thresh = cv2.threshold(image, 225, 255, cv2.THRESH_BINARY_INV)[1]
mask = thresh.copy()
mask = cv2.erode(mask, None, iterations=5)
cv2.imshow (mask)
Cv2.waitkey(0)
وتكون النتيجة كما هي موضحة في الشكل أدناه.
الشكل-16 إجراء عمليّة التوسعة
الخاتمة
وتعرّفنا على بعض التوابع وكيفيّة عملها، يمكنك تجريب الأكواد البرمجيّة السابقة، و أيضًا يمكن النظر إلى التوثيقات الخاصّ بالمكتبة، والتعرّف على الطرق الأخرى والميزات الكثيرة لهذه المكتبة، ربما في مقالات لاحقة نتحدّث عن مجال الرؤية الحاسوبيّة وتطبيقاته بشكل خاصّ باستخدام هذه المكتبة.
5 تعليقات
تحية واحترام،
المقال فوق الممتاز
نتمني نشر المزيد ف الايام القادمة بصورة متقاربة.
كل الشكر لك استاذ هذا ماتسعى له مدوتنا
كيف يمكن تحويل مثل تللك الصورة الى ملف وورد اقدر اعدل على صوره ونصه
https://drive.google.com/file/d/1WjJO-gJ6dLFqy-LrzHXuX4BOeIY6lcFC/view?usp=drivesdk
شكراً لكِ يا استاذتنا القديرة
هل يمكننا الحصول على شرح لمكتبة opencv في لغة C#
السلام عليكم احتاج مساعد في كيفية برمجه الصور الفضائية بلغه البايثون الي يعرف لا يقصر بالمساعده رجاء ؟